1. 程式人生 > >[Unity3D]Unity3D遊戲開發之滑鼠旋轉、縮放實現3D物品展示

[Unity3D]Unity3D遊戲開發之滑鼠旋轉、縮放實現3D物品展示

各位朋友,大家好,我是秦元培,歡迎大家關注我的博主,我的部落格地址是blog.csdn.net/qinyuanpei。最近博主重點研究了攝像機旋轉、縮放等問題,那麼今天為大家分享的是一個在3D展示中比較常用的功能,即通過滑鼠右鍵實現旋轉、滑鼠滾輪實現縮放、滑鼠中鍵實現平移。本文采用的方法依然是在[Unity3D]Unity3D遊戲開發之自由視角下的角色控制這篇文章中所採用的方法,所以如果大家對於這部分內容不太瞭解的話,最好先去看看這篇文章。好了,下面我們將以一個具體的例項來講解今天的內容。如圖,是博主建立的一個簡單地場景。我們希望實現通過滑鼠右鍵實現對角色的旋轉、滑鼠滾輪實現對角色的縮放、滑鼠中鍵實現對角色的平移。

using UnityEngine;
using System.Collections;

public class FreeView : MonoBehaviour
{

    //觀察目標
    public Transform Target;

    //觀察距離
    public float Distance = 5F;

    //旋轉速度
    private float SpeedX = 240;
    private float SpeedY = 120;

    //角度限制
    private float MinLimitY = -180;
    private float MaxLimitY = 180;

    //旋轉角度
    private float mX = 0.0F;
    private float mY = 0.0F;

    //滑鼠縮放距離最值
    private float MaxDistance = 10;
    private float MinDistance = 1.5F;
    //滑鼠縮放速率
    private float ZoomSpeed = 2F;

    //是否啟用差值
    public bool isNeedDamping = true;
    //速度
    public float Damping = 10F;

    //儲存角度的四元數
    private Quaternion mRotation;

    //定義滑鼠按鍵列舉
    private enum MouseButton
    {
        //滑鼠左鍵
        MouseButton_Left = 0,
        //滑鼠右鍵
        MouseButton_Right = 1,
        //滑鼠中鍵
        MouseButton_Midle = 2
    }

    //相機移動速度
    private float MoveSpeed = 5.0F;
    //螢幕座標
    private Vector3 mScreenPoint;
    //座標偏移
    private Vector3 mOffset;

    void Start()
    {
        //初始化旋轉角度
        mX = transform.eulerAngles.x;
        mY = transform.eulerAngles.y;
    }

    void LateUpdate()
    {
        //滑鼠右鍵旋轉
        if (Target != null && Input.GetMouseButton((int)MouseButton.MouseButton_Right))
        {
            //獲取滑鼠輸入
            mX += Input.GetAxis("Mouse X") * SpeedX * 0.02F;
            mY -= Input.GetAxis("Mouse Y") * SpeedY * 0.02F;
            //範圍限制
            mY = ClampAngle(mY, MinLimitY, MaxLimitY);
            //計算旋轉
            mRotation = Quaternion.Euler(mY, mX, 0);
            //根據是否插值採取不同的角度計算方式
            if (isNeedDamping)
            {
                transform.rotation = Quaternion.Lerp(transform.rotation, mRotation, Time.deltaTime * Damping);
            }
            else
            {
                transform.rotation = mRotation;
            }
        }

        //滑鼠中鍵平移


        //滑鼠滾輪縮放
        Distance -= Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
        Distance = Mathf.Clamp(Distance, MinDistance, MaxDistance);

        //重新計算位置
        Vector3 mPosition = mRotation * new Vector3(0.0F, 0.0F, -Distance) + Target.position;

        //設定相機的位置
        if (isNeedDamping)
        {
            transform.position = Vector3.Lerp(transform.position, mPosition, Time.deltaTime * Damping);
        }
        else
        {
            transform.position = mPosition;
        }

    }


    //角度限制
    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);
    }
}

家是不是覺得這部分程式碼很熟悉?不錯,這裡的原理都是一樣的,大家只要掌握核心原理就可以了,即首先根據滑鼠輸入來計算旋轉角、然後通過滾輪輸入計算距離、最後通過四元數運算計算相機的角度和距離。

。好了,最後我們再來做一個遷移,我們將把這個功能移植到Android平臺上,本來想把這部分作為Android手勢控制單獨寫一篇文章的,可是感覺這裡的程式碼都是相似的,再寫一篇實在沒有必要,所以,就直接給出程式碼吧!

    using UnityEngine;  
    using System.Collections;  
      
    public class MobileInput : MonoBehaviour {  
      
        //觀察目標  
        public Transform Target;  
      
        //觀察距離  
        public float Distance = 2F;  
      
        //距離最值  
        public float MaxDistance=5F;  
        public float MinDistance=0.5F;  
      
        //縮放速率  
        private float ZoomSpeed=0.15F;  
      
        //旋轉速度  
        private float SpeedX=240;  
        private float SpeedY=120;  
        //角度限制  
        private float  MinLimitY = 5;  
        private float  MaxLimitY = 180;  
          
        //旋轉角度  
        private float mX=0;  
        private float mY=0;  
      
        //當前手勢  
        private Vector2 mPos;  
      
        void Start ()   
        {  
            //允許多點觸控  
            Input.multiTouchEnabled=true;  
            //初始化旋轉  
            mX=Target.eulerAngles.x;  
            mY=Target.eulerAngles.y;  
        }  
      
        void Update ()   
        {  
            if(!Target) return;  
      
      
            //單點觸控  
            if(Input.touchCount==1)  
            {  
                //手指處於移動狀態  
                if(Input.touches[0].phase==TouchPhase.Moved)  
                {  
                    mX+=Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
                    mY-=Input.GetAxis("Mouse X") * SpeedY * 0.02F;  
                    mY=ClampAngle(mY,MinLimitY,MaxLimitY);  
                }  
            }  
      
            //多點觸控  
            if(Input.touchCount>1)  
            {  
                //兩隻手指都處於移動狀態  
                if(Input.touches[0].phase==TouchPhase.Moved || Input.touches[1].phase==TouchPhase.Moved)  
                {  
                    //計算移動方向  
                    Vector2 mDir=Input.touches[1].position-Input.touches[0].position;  
                    //根據向量的大小判斷當前手勢是放大還是縮小  
                    if(mDir.sqrMagnitude>mPos.sqrMagnitude){  
                        Distance-=ZoomSpeed;  
                    }else{  
                        Distance+=ZoomSpeed;  
                    }  
                    //限制距離  
                    Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
                    //更新當前手勢  
                    mPos=mDir;  
                }  
            }  
      
            //計算相機的角度和位置  
            transform.rotation=Quaternion.Euler(new Vector3(mY,mX,0));  
            transform.position=transform.rotation * new Vector3(0,0,-Distance)+Target.position;  
        }  
      
        //角度限制  
        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);  
        }  
    }  

以下新增滑鼠旋轉被選中物體

原文轉載自http://blog.csdn.net/zooen2011/article/details/14051025

滑鼠旋轉被選中的物體

1.X軸在平面座標是左右方向,這裡得到的是左右移動距離
2.移動距離得到了,接下來要考慮以那個軸為中心作旋轉
3.這裡要實現固定攝像機位置的情況下旋轉物體,就以Y軸為中心,所以Rotate(0,mousX,0);


    public float roate_Speed=100.0f;//旋轉速度  
    void Update()  
    {  
    Transform target_transform = null;//不用繫結物件,下面程式碼動態獲取物件  
    if (Input.GetMouseButton(0))  
                {  
                     
                    //在螢幕上轉換座標:將滑鼠點轉換成射線  
                    Ray rayObj = Camera.main.ScreenPointToRay(Input.mousePosition);  
                    RaycastHit hitObj;  
                    if (Physics.Raycast(rayObj, out hitObj))  
                    {  
                        //Debug.Log("射線得到的物件名稱:" + hitObj.collider.name);  
                        target_transform = hitObj.transform;  
                    }  
      
      
                    if (target_transform != null)  
                    {  
                        //Debug.Log("射線取得物件");  
                        float mousX = Input.GetAxis("Mouse X") * roate_Speed;//得到滑鼠移動距離  
                        target_transform.transform.Rotate(new Vector3(0, -mousX, 0));  
                    }  
                    else  
                    {  
                        Debug.Log("無法取得物件");  
                    }  
                }  
    }