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);
        }
    }

  • 相关阅读:
    POJ 2923 Relocation (状态压缩,01背包)
    HDU 2126 Buy the souvenirs (01背包,输出方案数)
    hdu 2639 Bone Collector II (01背包,求第k优解)
    UVA 562 Dividing coins (01背包)
    POJ 3437 Tree Grafting
    Light OJ 1095 Arrange the Numbers(容斥)
    BZOJ 1560 火星藏宝图(DP)
    POJ 3675 Telescope
    POJ 2986 A Triangle and a Circle
    BZOJ 1040 骑士
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/12355158.html
Copyright © 2011-2022 走看看