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

 

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM