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

 

}

posted @ 2017-02-21 13:14  muyouking  阅读(22088)  评论(0编辑  收藏  举报