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

    }

  • 相关阅读:
    poj 3415 后缀数组+单调栈
    hdu 3450 后缀数组
    hdu 2774 后缀数组
    后缀数组模板(倍增法)
    hdu 4405 概率dp
    zoj 3329 概率dp
    [日常摸鱼]bzoj2875[NOI2012]随机数生成器-矩阵快速幂
    [日常摸鱼]bzoj1038[ZJOI2008]瞭望塔-半平面交
    [日常摸鱼]bzoj1007[HNOI2008]水平可见直线-半平面交(对偶转凸包)
    [日常摸鱼]bzoj3083遥远的国度-树链剖分
  • 原文地址:https://www.cnblogs.com/muyouking/p/6423658.html
Copyright © 2011-2022 走看看