본문 바로가기

프로그램/유니티 스크립트 소스

[유니티 스크립트 소스] 오토(Auto) 카메라

728x90
반응형

유니티에서 제공하는 AutoCamera를 하나의 클래스로 만든 소스입니다.

 

using UnityEngine; 

public class AutoCamera : MonoBehaviour 
{ 
    public Transform m_Target; 
    private Rigidbody m_TargetRigidbody; 

    public float m_MoveSpeed = 3; 
    public float m_TurnSpeed = 1; 
    public float m_RollSpeed = 0.2f; 
    public bool m_FollowVelocity = false; 
    public bool m_FollowTilt = true; 
    public float m_SpinTurnLimit = 90; 
    public float m_TargetVelocityLowerLimit = 4f; 
    public float m_SmoothTurnTime = 0.2f; 

    private float m_LastFlatAngle; 
    private float m_CurrentTurnAmount; 
    private float m_TurnSpeedVelocityChange; 
    private Vector3 m_RollUp = Vector3.up; 

    void Start() 
    { 
        if (m_Target) 
            m_TargetRigidbody = m_Target.GetComponent<Rigidbody>(); 
    } 

    void FixedUpdate() 
    { 
        FollowTarget(Time.deltaTime); 
    } 
     
    private void FollowTarget(float deltaTime) 
    { 
        if (!(deltaTime > 0) || m_Target == null) 
        { 
            return; 
        } 

        var targetForward = m_Target.forward; 
        var targetUp = m_Target.up; 

        if (m_FollowVelocity && Application.isPlaying) 
        { 
            if (m_TargetRigidbody.velocity.magnitude > m_TargetVelocityLowerLimit) 
            { 
                targetForward = m_TargetRigidbody.velocity.normalized; 
                targetUp = Vector3.up; 
            } 
            else 
            { 
                targetUp = Vector3.up; 
            } 
            m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, 1, ref m_TurnSpeedVelocityChange, m_SmoothTurnTime); 
        } 

        else 
        { 
            var currentFlatAngle = Mathf.Atan2(targetForward.x, targetForward.z) * Mathf.Rad2Deg; 
            if (m_SpinTurnLimit > 0) 
            { 
                var targetSpinSpeed = Mathf.Abs(Mathf.DeltaAngle(m_LastFlatAngle, currentFlatAngle)) / deltaTime; 
                var desiredTurnAmount = Mathf.InverseLerp(m_SpinTurnLimit, m_SpinTurnLimit * 0.75f, targetSpinSpeed); 
                var turnReactSpeed = (m_CurrentTurnAmount > desiredTurnAmount ? .1f : 1f); 
                if (Application.isPlaying) 
                { 
                    m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, desiredTurnAmount, 
                                                            ref m_TurnSpeedVelocityChange, turnReactSpeed); 
                } 
                else 
                { 
                    m_CurrentTurnAmount = desiredTurnAmount; 
                } 
            } 
            else 
            { 
                m_CurrentTurnAmount = 1; 
            } 
            m_LastFlatAngle = currentFlatAngle; 
        } 

        transform.position = Vector3.Lerp(transform.position, m_Target.position, deltaTime * m_MoveSpeed); 

        if (!m_FollowTilt) 
        { 
            targetForward.y = 0; 
            if (targetForward.sqrMagnitude < float.Epsilon) 
            { 
                targetForward = transform.forward; 
            } 
        } 
        var rollRotation = Quaternion.LookRotation(targetForward, m_RollUp); 

        m_RollUp = m_RollSpeed > 0 ? Vector3.Slerp(m_RollUp, targetUp, m_RollSpeed * deltaTime) : Vector3.up; 
        transform.rotation = Quaternion.Lerp(transform.rotation, rollRotation, m_TurnSpeed * m_CurrentTurnAmount * deltaTime); 
    } 
}

 

 

 

 

 

728x90
반응형