zoukankan      html  css  js  c++  java
  • Unity 3D:控制相机旋转、移动、缩放等功能

    使用方法:创建一个无实际用途的 Cube( 其他亦可),并设置为隐藏,重命名为:CenterMod。若使用调整功能请使用函数 MoveMod(模型名) 即可。

    using UnityEngine;
    using System.Collections;
    using System;
    
    public class ControlCamera : MonoBehaviour
    {
    
        public static bool Kongrotating = true;
    
        //-----------------  初始参数  -----------------
       
        //--旋转速度
        private float xSpeed = 125.0f;
        private float ySpeed = 60.0f;
       
        //--缩放速度
        private float wheelSpeed = 50;
       
        //--移动速度
        private float xMoveSpeed = 200;
        private float yMoveSpeed = 200;
       
        //--是否无限制放大,但仍旧会受移动限制所规定的范围
        private bool IsYYFD = true;
        //--镜头与中心点距离,在 IsYYFD 变量为 true 时有效
        public static float JvLi;
       
        //-----------------  移动限制  -----------------
       
        //--是否允许移动相机
            public static bool IsCanMove;
        //--是否允许旋转相机
            public static bool IsCanRotate;
        //--是否允许缩放相机
            public static bool IsCanZoom;
       
        //--是否开启位置限制
            private bool IsCheck;
        //--缩放限制,最大,最小
            private float MaxWheel = 300;
            private float MinWheel = 8;
       
        //--移动限制
       
            //x轴 最大值、最小值
            private float xMaxMove = 94;
            private float xMinMove = -94;
            //y轴 最大值、最小值
            private float yMaxMove = 58;
            private float yMinMove = 1;
            //z轴 最大值、最小值
            private float zMaxMove = 44;
            private float zMinMove = -44;
       
        //中心点物体
        public static Transform Tanks;
        //缩放控制
        private float distance;
        //位置控制
        private Vector3 position;
        //角度控制
        private Quaternion rotation;
        //相机动画控制:0停止;1旋转指定角度;2旋转到某个角度
        static int Ani_Camera;
        //旋转动画的角度
        static float XAniAngle = 0f;
        static float YAniAngle = 0f;
        static float ZAniAngle = 0f;
        //旋转动画的方向
        static bool XFX;
        static bool YFX;
        static bool ZFX;
        //是否强行跳转
        static bool IsQXTZ = false;
        //是否跟随事件移动
        public static bool IsFollow = false;
        //锁定物体名称
        static string LockModName = "";
        //旋转速度
        static float XZSD = 1;
        //-----------------  无需改动,中间变量  -----------------
       
        //旋转角度(二维屏幕)
        public static float x = 90.0f;
        public static float y = 30.0f;
        public static float z = 0.0f;
        //坐标还原点
        private Vector3 LPosition;
        //中心物体坐标还原点
        private Vector3 LTPosition;
       
        //-----------------  公用函数  -----------------
       
        //使相机跳转到模型
        public static bool MoveToMod ( string ModName )
        {
            if (ModName == null || ModName == "") return false;
            //获得模型名称的GameObject
            Transform newTran = GameObject.Find(ModName).transform;
            //如果获取到了
            if (newTran != null)
            {
                //设置相机位置
                Tanks.position = newTran.position;
                IsQXTZ = true;
                //返回成功
                return true;
            }
            //如果失败
            else
            {
                //返回假
                return false;
            }
        }
        //使相机跳转到模型并按一定角度跳转
        public static void CameraRotate ( string ModName, float XAngle, float YAngle, float ZAngle, float Velocity, bool LsFollow )
        {
            //设置是否跟随视角
            IsFollow = LsFollow;
            //设置相机位置
            LockModName = ModName;
            //设置旋转角度
            XAniAngle = XAngle;
            YAniAngle = YAngle;
            ZAniAngle = ZAngle;
            //设置速度
            XZSD = Velocity;
            //初始化相机动画控制
            Ani_Camera = 1;
        }
        //相机旋转到某个角度
        public static void CameraRotateTo (string ModName, float XAngle, float YAngle, float ZAngle, float Velocity, bool LsFollow)
        {
            //throw new Exception(ModName);
            //设置是否跟随视角
            IsFollow = LsFollow;
            //设置相机位置
            LockModName = ModName;
            //设置旋转角度
            XAniAngle = XAngle;
            YAniAngle = YAngle;
            ZAniAngle = ZAngle;
            //设置速度
            XZSD = Velocity;
            //定义偏移速度
            XFX = ( XAniAngle > x ) ? true : false ;
            YFX = ( YAniAngle > y ) ? true : false ;
            ZFX = ( ZAniAngle > z ) ? true : false ;
            //开启动画控制
            Ani_Camera = 2;
           
        }
        //停止旋转
        public static void StopXZ()
        {
            Ani_Camera = 0;
        }
        //格式化X、Y、Z轴
        public static void FormatXYZ()
        {
            y = y % 360;
            x = x % 360;
            z = z % 360;
            //y = (360+y) % 360;
            //x = (360+x) % 360;
            //z = (360+z) % 360;
            //if (y < 0) y = 360 + y;
            //if (x < 0) x = 360 + x;
            //if (z < 0) z = 360 + z;
        }
    
        //-----------------  系统函数  -----------------
        void Start()
        {
            //初始化中心模块
            Tanks = GameObject.Find("CenterMod").transform;
            //初始化相机动画控制器
            Ani_Camera = 0;
            //初始化相机控制权,默认全部允许
            IsCanMove = true;
            IsCanRotate = true;
            IsCanZoom = true;
            //开启移动范围距离
            IsCheck = true;
            //关闭相机视角锁定
            IsFollow = false;
            //初始化相机位置
            transform.position = new Vector3(-20.8f, 33.8f, 36.9f);
            //初始化相机与中心模型的距离
            JvLi = 30;
            //初始化相机角度
            x = 180;y = 45;z = 0;
            //初始化中心物体位置
            Tanks.position = new Vector3(-19.6f, 6.7f, 5.2f);
            //初始化中心物体角度
            Tanks.rotation = Quaternion.Euler(0,0,0);
            //强制旋转
            IsQXTZ = true;
        }
       
        void Update()
        {
            if (!Kongrotating) return;
            //如果没有得到中心模块则此脚本无效
            if (Tanks == null) return;
            //初始坐标还原点
            LPosition = transform.position;
            //初始中心物体坐标还原点
            LTPosition = Tanks.position;
            if (IsFollow) MoveToMod(LockModName);
    
            if (Input.GetKey(KeyCode.LeftArrow) ||Input.GetKey(KeyCode.A))
            {
                x -= 2;
            }
            else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
            {
                x += 2;
            }
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
            {
                y--;
            }
            else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
            {
                y++;
            }
            if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
            {
                transform.Translate(Vector3.forward * 30 * Time.deltaTime);
                Tanks.Translate(Vector3.forward * 30 * Time.deltaTime);
            }
            else if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))
            {
                transform.Translate(Vector3.forward * -30 * Time.deltaTime);
                Tanks.Translate(Vector3.forward * -30 * Time.deltaTime);
            }
    
            //旋转指定角度相机动画
            if ( Ani_Camera == 1 )
            {
               
                //当还有剩余旋转角度则继续旋转
                if ( XAniAngle > 0 )
                {
                    //横向坐标加旋转速度
                    x+=XZSD;
                    //剩余角度减去速度
                    XAniAngle-=XZSD;
                }
                if ( YAniAngle > 0 )
                {
                    //横向坐标加旋转速度
                    y+=XZSD;
                    //剩余角度减去速度
                    YAniAngle-=XZSD;
                }
                //如果没有剩余旋转角度
                if (YAniAngle <= 0 && XAniAngle <= 0)
                {
                    //设置强制跳转无效
                    IsQXTZ = false;
                    //关闭动画控制器
                    Ani_Camera = 0;
                    //取消跟踪
                    IsFollow = false;
                }
            }
            //旋转到角度动画
            else if ( Ani_Camera == 2 )
            {
                //检查是否完成
                int IsCom = 0;
                if (!XFX && XAniAngle < x - XZSD)
                {
                    x -= XZSD;
                }
                else if (XFX && XAniAngle > x + XZSD)
                {
                    x += XZSD;
                }
                else if ((!XFX && XAniAngle >= x - XZSD) || (XFX && XAniAngle <= x + XZSD))
                {
                    IsCom++;
                }
                if (!YFX && YAniAngle < y - XZSD)
                {
                    y -= XZSD;
                }
                else if (YFX && YAniAngle > y + XZSD)
                {
                    y += XZSD;
                }
                else if ((!YFX && YAniAngle >= y - XZSD) || (YFX && YAniAngle <= y + XZSD))
                {
                    IsCom++;
                }
                if (!ZFX && ZAniAngle < z - XZSD)
                {
                    z -= XZSD;
                }
                else if (ZFX && ZAniAngle > z + XZSD)
                {
                    z += XZSD;
                }
                else if ((!ZFX && ZAniAngle >= z - XZSD) || (ZFX && ZAniAngle <= z + XZSD))
                {
                    IsCom++;
                }
                IsQXTZ = true;
                if (IsCom >= 3)
                {
                    //设置强制跳转无效
                    //IsQXTZ = false;
                    //关闭动画控制器
                    Ani_Camera = 0;
                    //关闭锁定模型
                    IsFollow = false;
                }
               
            }
            //获取相机与模型的距离
            distance = Vector3.Distance(transform.position,Tanks.position);
            //检查相机是否是以无效放大的模式
            if ( IsYYFD )
            {
                //是则缩放时方快跟随移动
                transform.Translate(Vector3.forward * Input.GetAxis("Mouse ScrollWheel") * wheelSpeed);
                Tanks.Translate(Vector3.forward * Input.GetAxis("Mouse ScrollWheel") * wheelSpeed);
               
                //方块与相机保持相应距离
                distance = JvLi;
            }
            else
            {
                //限制缩放
                if ( (Input.GetAxis("Mouse ScrollWheel") < 0 || distance > MinWheel) && (Input.GetAxis("Mouse ScrollWheel") > 0 || distance < MaxWheel) || !IsCheck || IsQXTZ )
                    //如果允许缩放
                    if ( IsCanZoom )
                        //缩放相机
                        distance -= Input.GetAxis("Mouse ScrollWheel")*wheelSpeed;
            }
           
            //按下鼠标右键执行旋转
            if(Input.GetMouseButton(1) && IsCanRotate)
            {
                //设置横向旋转距离
                x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                //设置纵向旋转距离
                y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
            }
            //格式化 x y z 坐标,使之不可超越-360~360
            FormatXYZ();
            //设置角度
            rotation = Quaternion.Euler(y, x, z);
            //设置位置
            position = rotation * new Vector3(0.0f, 0.0f, -distance) + Tanks.position;
            //更新角度
            Tanks.rotation = rotation;
            //更新位置
            if (Input.GetMouseButton(1) && IsCanRotate || IsQXTZ)
            {
                transform.position = position;
                IsQXTZ = false;
            }
            else
            {
                transform.position = rotation * new Vector3(0.0f, 0.0f, 0.0f) + transform.position;
            }
            Tanks.position = rotation * new Vector3(0.0f, 0.0f, 0.0f) + Tanks.position;
            //鼠标中间平移
            if ( Input.GetMouseButton(2) && IsCanMove)
            {
                //横向平移
                transform.Translate(Vector3.right * xMoveSpeed * Time.deltaTime * -Input.GetAxis("Mouse X"));
                //纵向平移,若相机垂直地面则向前平移
                transform.Translate(Vector3.up * yMoveSpeed * Time.deltaTime * -Input.GetAxis("Mouse Y"));
               
                //横向平移
                Tanks.Translate(Vector3.right * xMoveSpeed * Time.deltaTime * -Input.GetAxis("Mouse X"));
                //纵向平移,若相机垂直地面则向前平移
                Tanks.Translate(Vector3.up * yMoveSpeed * Time.deltaTime * -Input.GetAxis("Mouse Y"));
            }
            //检查相机x轴
            if ( (transform.position.x > xMaxMove || transform.position.x < xMinMove) && IsCheck )
            {
                transform.position = new Vector3(LPosition.x,transform.position.y,transform.position.z);
            }
            //检查相机y轴
            if ( (transform.position.y > yMaxMove || transform.position.y < yMinMove) && IsCheck )
            {
                transform.position = new Vector3(transform.position.x,LPosition.y,transform.position.z);
            }
            //检查相机z轴
            if ( (transform.position.z > zMaxMove || transform.position.z < zMinMove) && IsCheck )
            {
                transform.position = new Vector3(transform.position.x,transform.position.y,LPosition.z);
            }
           
            //检查中心物体x轴
            if ( (Tanks.position.x > xMaxMove || Tanks.position.x < xMinMove) && IsCheck )
            {
                Tanks.position = new Vector3(LTPosition.x,Tanks.position.y,Tanks.position.z);
            }
            //检查中心物体y轴
            if ( (Tanks.position.y > yMaxMove || Tanks.position.y < yMinMove) && IsCheck )
            {
                Tanks.position = new Vector3(Tanks.position.x,LTPosition.y,Tanks.position.z);
            }
            //检查中心物体z轴
            if ( (Tanks.position.z > zMaxMove || Tanks.position.z < zMinMove) && IsCheck )
            {
                Tanks.position = new Vector3(Tanks.position.x,Tanks.position.y,LTPosition.z);
            }
    
            //更新角度
            transform.rotation = Tanks.rotation;
        }
    }

    }

  • 相关阅读:
    leetcode 347. Top K Frequent Elements
    581. Shortest Unsorted Continuous Subarray
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 217. Contains Duplicate、219. Contains Duplicate II、220. Contains Duplicate、287. Find the Duplicate Number 、442. Find All Duplicates in an Array 、448. Find All Numbers Disappeared in an Array
    leetcode 461. Hamming Distance
    leetcode 19. Remove Nth Node From End of List
    leetcode 100. Same Tree、101. Symmetric Tree
    leetcode 171. Excel Sheet Column Number
    leetcode 242. Valid Anagram
    leetcode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/muyouking/p/6423658.html
Copyright © 2011-2022 走看看