zoukankan      html  css  js  c++  java
  • 第三人称相机

    using UnityEngine;
    
    public class PlayerCamera3rd : MonoBehaviour 
    {
        Vector3 m_defaultDir;
        Transform m_PlayerTransform;
        Vector3 m_RotateValue;
        Vector3 m_PitchRotateAxis;  //俯仰方向轴
        Vector3 m_YawRotateAxis;//左右横向旋转轴
    
    
        public float distance = 4;
        public float speed = 120f;
        public Vector3 offest = new Vector3(0, 1.5f, 0);
        public float followRange = 0.5f;
        Vector3 followPoint;
    
        //翻转pitch方向相机旋转 
        public bool invertPitch;
        public Vector2 pitchLimit = new Vector2(-40f,85f);
    
        //修改相机位置缓动
        float m_CurrentDistance;
        float m_DistanceRecoveryDelayCounter;
        public float distanceRecoverySpeed = 4f;
        public float distanceRecoveryDelay = 0.3f;
    
        public Transform followPlayer;
    
        Vector3 upAxis;
        void OnEnable()
        {
            if (followPlayer == null)
            {
                m_PlayerTransform = GameObject.FindGameObjectWithTag("Player").transform;
            }
            else
                m_PlayerTransform = followPlayer;
            followPoint = m_PlayerTransform.position;
             upAxis = -Physics.gravity.normalized;
            m_defaultDir = Vector3.ProjectOnPlane((transform.position - m_PlayerTransform.position), upAxis).normalized;
            
            m_YawRotateAxis = upAxis;
    
    
        }
    
        void LateUpdate()
        {
            Vector2 inputDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
            m_RotateValue.x += inputDelta.x * speed * Time.smoothDeltaTime;
            m_RotateValue.x = AngleCorrection(m_RotateValue.x);
    
            m_RotateValue.y += inputDelta.y * speed * (invertPitch ? -1 : 1) * Time.smoothDeltaTime;
            m_RotateValue.y = AngleCorrection(m_RotateValue.y);
    
            m_RotateValue.y = Mathf.Clamp(m_RotateValue.y, pitchLimit.x, pitchLimit.y);
    
            var horizontalQuat = Quaternion.AngleAxis(m_RotateValue.x, m_YawRotateAxis);
            m_PitchRotateAxis = Vector3.Cross(upAxis, Vector3.ProjectOnPlane(transform.forward, upAxis));
            var verticalQuat = Quaternion.AngleAxis(m_RotateValue.y, m_PitchRotateAxis);
    
            var finalDir = horizontalQuat * verticalQuat * m_defaultDir;
            var from = m_PlayerTransform.localToWorldMatrix.MultiplyPoint3x4(offest);
            var to = from + finalDir * distance;
            var exceptTo = ObstacleProcess(from, to);
    
            var expectDistance = Vector3.Distance(exceptTo, from);
    
            followPoint= UpdateFocusPoint(m_PlayerTransform,followRange);
            m_CurrentDistance = (followPoint - transform.position).magnitude;
    
            //Debug.Log(m_CurrentDistance);
            if (expectDistance < m_CurrentDistance)
            {
                m_CurrentDistance = expectDistance;
                m_DistanceRecoveryDelayCounter = distanceRecoveryDelay;
    
            }
            else
            {
                if (m_DistanceRecoveryDelayCounter > 0f)
                    m_DistanceRecoveryDelayCounter -= Time.deltaTime;
                else
                {
                    m_CurrentDistance = Mathf.Lerp(m_CurrentDistance, expectDistance, Time.smoothDeltaTime * distanceRecoverySpeed);
                }
            }
            transform.position = Vector3.Slerp(transform.position,from + finalDir * m_CurrentDistance,Time.deltaTime* distanceRecoverySpeed);
            transform.LookAt(from);
        }
        /// <summary>
        /// 更新相机跟随点位置
        /// </summary>
        /// <param name="m_PlayerTransform"></param>
        /// <param name="followRange"></param>
        /// <returns></returns>
        Vector3 UpdateFocusPoint(Transform m_PlayerTransform,float followRange)
        {
            Vector3 followPoint = m_PlayerTransform.position;
            if (followRange>0)
            {
                if ((m_PlayerTransform.position - followPoint).magnitude > followRange)
                {
                    followPoint = Vector3.Slerp(followPoint, m_PlayerTransform.position, Time.deltaTime * distanceRecoverySpeed);
                }
                
            }
            else
            {
                followPoint = m_PlayerTransform.position;
            }
            return followPoint;
        }
        float AngleCorrection(float value)
        {
            if (value > 180f) return m_RotateValue.x - 360f;
            else if (value < -180f) return m_RotateValue.x + 360f;
            return value;
        }
        public LayerMask obstacleLayerMask; 
        public float obstacleSphereRadius = 0.3f;  
       
        Vector3 ObstacleProcess(Vector3 from,Vector3 to)
        {
            var dir = (to - from).normalized;
            var hit = default(RaycastHit);
            var isHit = Physics.SphereCast(new Ray(from, dir), obstacleSphereRadius, out hit, distance, obstacleLayerMask);
            if (isHit)
            {
                return hit.point + (-dir * obstacleSphereRadius);
            }
            return to; 
        }
    }
  • 相关阅读:
    AdminLTE模板
    日历插件
    Jquery 拖拽表格宽度
    Java桌面程序打包成exe可执行文件
    使用Access-Control-Allow-Origin解决跨域
    Ubuntu默认root密码
    Lua的require和module小结
    nginx 安装
    chkconfig命令
    [转]fedora启动telnet服务
  • 原文地址:https://www.cnblogs.com/DazeJiang/p/14341037.html
Copyright © 2011-2022 走看看