美文网首页
一、视角控制:3DRPG手游第三人称自由视角控制

一、视角控制:3DRPG手游第三人称自由视角控制

作者: GameObjectLgy | 来源:发表于2021-01-19 21:51 被阅读0次

    功能点:
    1、相机缓动跟随。
    2、相机根据点击可以自由旋转环绕目标。
    3、PC上可以用鼠标滚轮实现远近缩放效果,在手机上可以用双点触摸进行缩放。

    using UnityEngine;
    
    /// <summary>
    /// Chinar相机脚本
    /// </summary>
    public class CameraCtl : MonoBehaviour
    {
        public Transform TargetTransform;                      // 手动添加:被跟踪的对象:pivot——以什么为轴
        public Vector3 pivotOffset = Vector3.zero; // 与目标的偏移量
        public float distance = 10.0f;     // 距目标距离(使用变焦)
        public float minDistance = 2f;        //最小距离
        public float maxDistance = 15f;       //最大距离
        public float zoomSpeed = 1f;        //速度倍率
        public float xSpeed = 250.0f;    //x速度
        public float ySpeed = 120.0f;    //y速度
        public bool allowYTilt = true;      //允许Y轴倾斜
        public float yMinLimit = 15f;      //相机向下最大角度
        public float yMaxLimit = 60;       //相机向上最大角度
        public float SmoothFllower = 0.5f;
    
        private float x = 0.0f;      //x变量
        private float y = 0.0f;      //y变量
        private float targetX = 0f;        //目标x
        private float targetY = 0f;        //目标y
        private float targetDistance = 0f;        //目标距离
        private float xVelocity = 1f;        //x速度
        private float yVelocity = 1f;        //y速度
        private float zoomVelocity = 1f;        //速度倍率
    
        void Start()
        {
            var angles = transform.eulerAngles;                          //当前的欧拉角
            targetX = x = angles.x;                                   //给x,与目标x赋值
            targetY = y = ClampAngle(angles.y, yMinLimit, yMaxLimit); //限定相机的向上,与下之间的值,返回给:y与目标y
            targetDistance = distance;                                       //初始距离数据为10;
        }
    
    
        void LateUpdate()
        {
            if (TargetTransform) //如果存在设定的目标
            {
    #if UNITY_IOS || UNITY_ANDROID
                 ZoomCtl();
                if (isZoom)
                {
                    if (isforward == 1)
                        targetDistance -= zoomSpeed;
                    else if (isforward == -1)
                        targetDistance += zoomSpeed;
                }        
                isZoom = false;   
    #else
                float scroll = Input.GetAxis("Mouse ScrollWheel"); //获取滚轮轴
                //如果大于0,说明滚动了:那么与目标距离,就减少固定距离1。就是向前滚动,就减少值,致使越来越近
                if (scroll > 0.0f)
                    targetDistance -= zoomSpeed;
                else if (scroll < 0.0f)
                    targetDistance += zoomSpeed;
    #endif
                
                //距离变远 
                //否则目标的距离限定在2-15之间
                targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);
    #if UNITY_IOS || UNITY_ANDROID
                if(Input.touchCount>0&&Input.GetTouch(0).phase == TouchPhased.Moved)
    #else
                if (Input.GetMouseButton(1) || Input.GetMouseButton(0) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))) //鼠标右键
    #endif
    
                {
                    Debug.Log("进行旋转");
                    targetX += Input.GetAxis("Mouse X") * xSpeed * 0.02f; //目标的x随着鼠标x移动*5
                    if (allowYTilt)                                       //y轴允许倾斜
                    {
                        targetY -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; //目标的y随着鼠标y移动*2.4
                        targetY = ClampAngle(targetY, yMinLimit, yMaxLimit); //限制y的移动范围在-90到90之间
                    }
                }
                x = Mathf.SmoothDampAngle(x, targetX, ref xVelocity, 0.3f);
                if (allowYTilt) y = Mathf.SmoothDampAngle(y, targetY, ref yVelocity, 0.3f);
                else y = targetY;
                Quaternion rotation = Quaternion.Euler(y, x, 0);
                distance = Mathf.SmoothDamp(distance, targetDistance, ref zoomVelocity, 0.5f);
                Vector3 position = rotation * new Vector3(0.0f, 0.0f, -distance) + TargetTransform.position + pivotOffset;
                transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * SmoothFllower);
                //transform.rotation = rotation;
                transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * SmoothFllower);
                //transform.position = position;
            }
        }
    
    
        /// <summary>
        /// 限定一个值,在最小和最大数之间,并返回
        /// </summary>
        /// <param name="angle"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private float ClampAngle(float angle, float min, float max)
        {
            if (angle < -360) angle += 360;
            if (angle > 360) angle -= 360;
            return Mathf.Clamp(angle, min, max);
        }
    
    #if UNITY_IOS || UNITY_ANDROID
        private bool isZoom = false;
        private void ZoomCtl()
        {
            if (Input.touchCount > 1)//多点触碰  
            {
                isZoom = true;
                //记录两个手指的位置  
                Vector2 nposition1 = new Vector2();
                Vector2 nposition2 = new Vector2();
    
                //记录手指的每帧移动距离  
                Vector2 deltaDis1 = new Vector2();
                Vector2 deltaDis2 = new Vector2();
    
                for (int i = 0; i < 2; i++)
                {
                    Touch touch = Input.touches[i];
                    if (touch.phase == TouchPhase.Ended)
                        break;
                    if (touch.phase == TouchPhase.Moved) //手指在移动  
                    {
    
                        if (i == 0)
                        {
                            nposition1 = touch.position;
                            deltaDis1 = touch.deltaPosition;
                        }
                        else
                        {
                            nposition2 = touch.position;
                            deltaDis2 = touch.deltaPosition;
    
                            if (isEnlarge(oposition1, oposition2, nposition1, nposition2)) //判断手势伸缩从而进行摄像机前后移动参数缩放效果  
                                isforward = 1;
                            else
                                isforward = -1;
                        }
                        //记录旧的触摸位置  
                        oposition1 = nposition1;
                        oposition2 = nposition2;
                    }
                    //移动摄像机  
                    //Camera.main.transform.Translate(isforward * Vector3.forward * Time.deltaTime * (Mathf.Abs(deltaDis2.x + deltaDis1.x) + Mathf.Abs(deltaDis1.y + deltaDis2.y)));
                }
            }
        }
    
        private int isforward;//标记摄像机的移动方向  
        //记录两个手指的旧位置  
        private Vector2 oposition1 = new Vector2();
        private Vector2 oposition2 = new Vector2();
    
        //Vector2 m_screenPos = new Vector2(); //记录手指触碰的位置  
        //用于判断是否放大  
        bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
        {
            //函数传入上一次触摸两点的位置与本次触摸两点的位置计算出用户的手势  
            float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
            float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
            if (leng1 < leng2)
            {
                //放大手势  
                return true;
            }
            else
            {
                //缩小手势  
                return false;
            }
        }
    #endif
    }
    

    相关文章

      网友评论

          本文标题:一、视角控制:3DRPG手游第三人称自由视角控制

          本文链接:https://www.haomeiwen.com/subject/xrnczktx.html