Unity 相机跟随某物体

特点:
可自定义设置:相机与被跟随目标的距离,移动到目标位置的速度,与目标位置的偏移角度。切换跟踪目标。

在这里插入图片描述

using UnityEngine;
using System.Collections.Generic;

namespace Ceto
{
    
    
    public class CameraFlowTarget : MonoBehaviour
    {
    
    
        struct Position
        {
    
    
            public Vector3 forwardAmount;
            public float turnAmount;
            public Vector3 camRotation;
            public float camDistance;
        }
        public List<GameObject> obj = new List<GameObject>();
        public bool disableInterpolation;
        public GameObject m_ship;
        public Vector3 m_forward = new Vector3(0, 0, 1);
        public float m_shipMoveSpeed = 20.0f;

        [Range(0.01f, 1.0f)]
        public float shipSmoothness = 0.5f;
        public float m_camRotationSpeed = 10.0f;
        public float m_camStartRotationX = 10.0f;
        public float m_camStartRotationY = 60.0f;
        public float m_camStartRotationZ = 60.0f;
        //跟目标点保持的距离
        public float m_camStartDistance = 200.0f;

        [Range(0.01f, 1.0f)]
        public float camSmoothness = 0.5f;
        Position m_position, m_target;
        const float MAX_ACCELERATION = 1.0f;
        const float ACCELERATION_RATE = 1.0f;
        const float DECELERATION_RATE = 0.25f;
        float m_acceleration = 0.0f;
        public GameObject target;
        Vector3 m_previousPos, m_velocity;
        public GameObject m_dummy;

        GameObject Ship
        {
    
    
            get
            {
    
    
                if (m_ship == null)
                {
    
    
                    m_dummy = new GameObject();
                    m_ship = m_dummy;
                }
                return m_ship;
            }
            set
            {
    
    
                m_ship = value;
            }
        }

        void Start()
        {
    
    
            TheForward();
        }

        void TheForward()
        {
    
    
            m_position.camRotation.x = m_camStartRotationX;
            m_position.camRotation.y = m_camStartRotationY;
            m_position.camRotation.z = m_camStartRotationZ;
            m_position.camDistance = m_camStartDistance;
            m_position.forwardAmount = Vector3.zero;
            m_target = m_position;
        }

        void LateUpdate()
        {
    
    
            //if (是否可通过拖拽鼠标控制视角变化)
            //{
    
    
                ProcessInput();
            //}

            InterpolateToTarget();

            //if (不是第一人称视角)
            //{
    
    
                MoveShip();
            //}

            CameraChange();

            //**实时测试相机与目标点的距离,角度偏移等**
            //TheForward();
        }

      
        void MoveShip()
        {
    
    
            Vector3 eulerAngles = Ship.transform.eulerAngles;
            eulerAngles.y += m_position.turnAmount;
            Ship.transform.eulerAngles = eulerAngles;

            float ct = Mathf.Cos(m_position.camRotation.y * Mathf.Deg2Rad);
            float st = Mathf.Sin(m_position.camRotation.y * Mathf.Deg2Rad);
            float cp = Mathf.Cos(m_position.camRotation.x * Mathf.Deg2Rad);
            float sp = Mathf.Sin(m_position.camRotation.x * Mathf.Deg2Rad);

            Vector3 lookAt = Ship.transform.position;
            Vector3 pos = lookAt + (new Vector3(sp * st, ct, cp * st)) * m_position.camDistance;

            transform.position = pos;
            transform.LookAt(lookAt);

            m_velocity = Ship.transform.position - m_previousPos;
            m_previousPos = Ship.transform.position;

        }

        void InterpolateToTarget()
        {
    
    

            if (disableInterpolation || Time.timeScale == 0.0f)
            {
    
    
                m_position = m_target;
                return;
            }
            float smoothness;
            smoothness = 1.0f / Mathf.Clamp(camSmoothness, 0.01f, 1.0f);
            float camLerp = Mathf.Clamp01(Time.deltaTime * smoothness);
            m_position.camDistance = Mathf.Lerp(m_position.camDistance, m_target.camDistance, camLerp);
            m_position.camRotation = Vector2.Lerp(m_position.camRotation, m_target.camRotation, camLerp);

            //smoothness = 1.0f / Mathf.Clamp(shipSmoothness, 0.01f, 1.0f);
            //float shipLerp = Mathf.Clamp01(Time.deltaTime * smoothness);
            //m_position.forwardAmount = Vector3.Lerp(m_position.forwardAmount, m_target.forwardAmount, shipLerp);
            //m_position.turnAmount = Mathf.Lerp(m_position.turnAmount, m_target.turnAmount, shipLerp);
        }

        void ProcessInput()
        {
    
    
            float speed = m_shipMoveSpeed;
            float velocity = m_velocity.magnitude;

            m_target.forwardAmount = Vector3.zero;
            m_target.turnAmount = 0.0f;


            m_acceleration = Mathf.Clamp(m_acceleration, 0.0f, MAX_ACCELERATION);

            float dt = Time.deltaTime * 2000.0f;
            float amount = Mathf.Pow(1.02f, Mathf.Min(dt, 1.0f));

            if (Input.GetAxis("Mouse ScrollWheel") < 0.0f)
            {
    
    
                m_target.camDistance *= amount;
            }

            else if (Input.GetAxis("Mouse ScrollWheel") > 0.0f)
            {
    
    
                m_target.camDistance /= amount;
            }
            m_target.camDistance = Mathf.Max(1.0f, m_target.camDistance);
            //相机旋转角度范围设置
            m_target.camRotation.y = Mathf.Clamp(m_target.camRotation.y, 20.0f, 140.0f);

            if (Input.GetMouseButton(0))
            {
    
    
                m_target.camRotation.y += Input.GetAxis("Mouse Y") * m_camRotationSpeed;
                m_target.camRotation.x += Input.GetAxis("Mouse X") * m_camRotationSpeed;
            }

        }
        public void CameraChange()
        {
    
    
            if (Input.GetKey("1"))
            {
    
    
                m_ship = obj[0];
            }
            if (Input.GetKey("2"))
            {
    
    
                m_ship = obj[1];
            }
        }

        //视角切换 (镜头缓慢移动)
        public void SwitchtoF16(int i, float camDis, float camrot)
        {
    
    
            m_ship = obj[i];
            m_target.camDistance = camDis;
            m_target.camRotation.x = camrot;
        }

        /// <summary>
        /// 视角切换(镜头快速切换)
        /// </summary>
        /// <param name="i">被跟随物体的序号</param>
        /// <param name="camDis">相机与被跟随物体的距离</param>
        /// <param name="camrx">相机与被跟随物体的夹角</param>
        /// <param name="camry">相机与被跟随物体高度差</param>
        public void SwitchtoMainview(int i, float camDis, float camrx, float camry)
        {
    
    
            m_ship = obj[i];
            m_target.camDistance = camDis;
            m_target.camRotation.x = camrx;
            m_target.camRotation.y = camry;
            m_position.camDistance = Mathf.Lerp(m_position.camDistance, m_target.camDistance, 1);
            m_position.camRotation = Vector2.Lerp(m_position.camRotation, m_target.camRotation, 1);
        }

        void OnDestroy()
        {
    
    
            if (m_dummy != null)
                DestroyImmediate(m_dummy);
        }
    }

}

猜你喜欢

转载自blog.csdn.net/qq_22975451/article/details/113347308