zoukankan      html  css  js  c++  java
  • Unity相机跟随小结

    做游戏的时候相机是我们的直接感官,相机的跟随方式严重关系到游戏的体验。我们最常用的跟随方式是

    transform.position = Vector3.Lerp(transform.position, GetTargetPos(player), deltaTime * speed);
    transform.rotation = Quaternion.Lerp(transform.rotation, GetTargetRotation(player), deltaTime * rSpeed);

    需要注意的是上面deltaTtime,需要根据目标物体的运动更新方式设置相应的值。如果目标物体的运动是物理速度或者物理更新,那么应该使用Time.FixedDeltaTIme,并且此段代码应该放在FixedUpate中。对于update下运动的物体,就应该使用Time.DeltaTIme。

    如果不这么做会常常发生抖动情况,甚至有时搞不清除到底是相机的问题还是目标自身的问题。

    下面是一个赛车游戏的相机跟随方式

    public class FollowCamera : MonoBehaviour
    {
        internal enum UpdateMode
        {
            Update,
            FixedUpdate
        }
    
        [SerializeField] UpdateMode updateMode=UpdateMode.Update;
        [SerializeField]Transform cam;
        [SerializeField]Transform player;
        [SerializeField]Vector3 offsetPos;
        [SerializeField] float speed;
        [SerializeField] float rSpeed;
        Vector3 pos;
        [SerializeField] Vector3 angel;//对目标的局部旋转
        Quaternion rotation;
    
        private void Awake()
        {
            player = GameObject.FindGameObjectWithTag("Player").transform;
        }
    
        // Update is called once per frame
        void Update()
        {
            if (updateMode != UpdateMode.Update) return;
            SetCameraPosLerp(UpdateMode.Update);
        }
    
        private void FixedUpdate()
        {
            if (updateMode != UpdateMode.FixedUpdate) return;
            SetCameraPosLerp(UpdateMode.FixedUpdate);
        }
    
        //获取目标位置
        Vector3 GetTargetPos(Transform target)
        {
            Vector3 p = target.TransformPoint(offsetPos);
            return p;
        }
    
        //获取目标旋转
        Quaternion GetTargetRotation(Transform target)
        {
            Quaternion r= Quaternion.Euler(angel);
            r = target.rotation * r;//跟随目标旋转的方式就是让目标旋转和局部旋转相乘
            return r;
        }
    
        //更新相机的旋转和位置
        void SetCameraPosLerp(UpdateMode mode)
        {
            if (!player) return;
            float deltaTime = 0;
            switch (mode)
            {
                case UpdateMode.Update:
                    deltaTime = Time.deltaTime;
                    break;
                case UpdateMode.FixedUpdate:
                    deltaTime = Time.fixedDeltaTime;
                    break;
            }
            transform.position = Vector3.Lerp(transform.position, GetTargetPos(player), deltaTime * speed);
            transform.rotation = Quaternion.Lerp(transform.rotation, GetTargetRotation(player), deltaTime * rSpeed);
        }
    
        //In Editor
        public void SetCameraPos()
        {
            if (!player) return;
            transform.position= GetTargetPos(player);
            transform.rotation = GetTargetRotation(player);
        }
    
        private void OnDrawGizmos()
        {
            if (!player) return;
            Gizmos.color = Color.red;
            Vector3 p = GetTargetPos(player);
            Gizmos.DrawWireSphere(p, 0.5f);
            Gizmos.DrawLine(p, player.position);
        }
    }

  • 相关阅读:
    python项目文件夹
    内置函数
    函数的递归
    python入门之模块
    匿名函数
    生成器表达式
    三元表达式
    列表生成式
    input相关问题总结
    表单验证
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/12355158.html
Copyright © 2011-2022 走看看