camera旋轉+模型移動

來源:互聯網
上載者:User

標籤:

    剛接觸Unity不久,正處於用什麼學什麼的狀態,遇到這個問題著實研究了一陣子,得到了一個比較笨的方法。

    想要完成的功能有兩個,一是攝像機繞著整個情境中的所有模型旋轉,旋轉的中心點是全局座標的原點;二是不管攝像機旋轉到什麼位置,模型都能跟隨滑鼠進行移動。

    單獨的讓攝像機繞全局座標原點旋轉可以使用transform.RotateAround(Vector3.zero, Vector3.down, mouseMovex * Time.deltaTime)。但是問題來了,如果只是進行水平方向或是垂直方向上的單方向的旋轉,簡單的使用transform.RotateAround(Vector3.zero, Vector3.down, mouseMovex * Time.deltaTime)是可以的;如果需要水平方向和垂直方向的混合旋轉,就會出現問題,而這個問題就出在Vector3.down上。對於使用者來說,在滑鼠拖拽旋轉的過程中,是以螢幕座標為準的。也就是說這個Vector3.down對於使用者來說是螢幕座標的y軸,只有第一次旋轉的時候螢幕座標的x、y軸與全局座標的x、y軸是重合的,只要攝像機進行過一次旋轉,螢幕座標與全局座標就不再重合。所以當多次旋轉時,就會出現混亂。不只是旋轉,滑鼠對模型的拖拽也會出現嚴重的偏差。這就需要在每一次旋轉前對旋轉軸進行修正。我的方法是在攝像機x方向加一和y方向加一各添加一個Empty GameObject與攝像機進行同步旋轉,作為方向標誌物。在每一次旋轉前,擷取攝像機與兩個方向標誌物的全局座標,進而計算出螢幕座標軸在全局座標中的方向向量,來確定攝像機的旋轉軸。代碼如下:

 1 using UnityEngine; 2 using System.Collections; 3  4 public class scencerotate : MonoBehaviour { 5  6     Vector2 mousePositionBefore, mousePositionAfter;     //用來記錄滑鼠的位置,以便計算旋轉幅度 7     private GameObject camera;      //儲存攝像機資訊 8     private GameObject xflagGameObject;     //儲存x方向標誌物的資訊 9     private GameObject yflagGameObject;     //儲存y方向標誌物的資訊10     private Vector3 xdirVector;     //螢幕座標x方向在全局座標中的方向向量11     private Vector3 ydirVector;     //螢幕座標y方向在全局座標中的方向向量12 13     // Use this for initialization14     void Start () 15     {        16     }17     18     // Update is called once per frame19     void Update () 20     {21         if (Input.GetMouseButtonDown(1))        //檢測滑鼠右鍵是否被按下22         {23             xflagGameObject = GameObject.Find("xFlag(Clone)");24             yflagGameObject = GameObject.Find("yFlag(Clone)");25             camera = GameObject.Find("Main Camera");26             xdirVector = xflagGameObject.transform.position - camera.transform.position;        //得到螢幕座標的x方向在全局座標系下的方向向量27             ydirVector = yflagGameObject.transform.position - camera.transform.position;        //得到螢幕座標的y方向在全局座標系下的方向向量28             mousePositionBefore = new Vector2(Input.mousePosition.x, Input.mousePosition.y);        //滑鼠右鍵按下時記錄滑鼠位置mousePositionBefore29         }30         if (Input.GetMouseButton(1))        //檢測滑鼠右鍵是否被按著31         {32             mousePositionAfter = new Vector2(Input.mousePosition.x, Input.mousePosition.y);     //滑鼠右鍵拖動時記錄滑鼠位置mousePositionAfter33             //下面開始旋轉34             float mouseMovex = (mousePositionAfter.x - mousePositionBefore.x) * 0.1f;35             float mouseMovey = (mousePositionAfter.y - mousePositionBefore.y) * 0.1f;36             transform.RotateAround(Vector3.zero, ydirVector, mouseMovex * Time.deltaTime);         //在螢幕座標系水平方向上進行旋轉37             transform.RotateAround(Vector3.zero, -xdirVector, mouseMovey) * Time.deltaTime);         //在螢幕座標系垂直方向上進行旋轉38          }39     }40 }

    把以上指令碼放到攝像機上即可。模型移動是一樣的方法

 1 using UnityEngine; 2 using System.Collections; 3  4 public class move : MonoBehaviour 5 { 6     private GameObject camera;      //儲存攝像機資訊 7     private GameObject xflagGameObject;     //儲存x方向標誌物的資訊 8     private GameObject yflagGameObject;     //儲存y方向標誌物的資訊 9     private Vector3 xdirVector;     //螢幕座標x方向在全局座標中的方向向量10     private Vector3 ydirVector;     //螢幕座標y方向在全局座標中的方向向量11     private Vector3 moveModel;      //模型在全局座標中的移動向量12 13     // Use this for initialization14 15     void Start()16     {17 18     }19 20     // Update is called once per frame21 22     void Update()23     {24 25     }26 27     //下面的函數是當滑鼠觸碰到碰撞體或者剛體時調用,我的碰撞體設定是mesh collider,然後別忘了,給這個collider添加物理材質28     //值得注意的是全局座標系轉化為螢幕座標系,Z軸是不變的29     IEnumerator OnMouseDown()30     {31        Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);       //將物體由全局座標系轉化為螢幕座標系 ,由vector3 結構體變數ScreenSpace儲存,以用來明確螢幕座標系Z軸的位置32         Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));     //完成了兩個步驟,1由於滑鼠的座標系是2維的,需要轉化成3維的全局座標系,2隻有三維的情況下才能來計算滑鼠位置與物體的距離,offset即是距離33 34         //當滑鼠左鍵按下時35         while (Input.GetMouseButton(0))36         {37             Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);       //得到現在滑鼠的2維座標系位置38             Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace);       //將當前滑鼠的2維位置轉化成三維的位置39 40             //判斷移動方向41             xflagGameObject = GameObject.Find("xFlag(Clone)");42             yflagGameObject = GameObject.Find("yFlag(Clone)");43             camera = GameObject.Find("Main Camera");44             xdirVector = xflagGameObject.transform.position - camera.transform.position;45             ydirVector = yflagGameObject.transform.position - camera.transform.position;46             moveModel.x = xdirVector.x * offset.x + ydirVector.x * offset.x;47             moveModel.y = xdirVector.y * offset.y + ydirVector.y * offset.y;48             moveModel.z = xdirVector.z * offset.z + ydirVector.z * offset.z;49             transform.position = new Vector3(curPosition.x + moveModel.x, curPosition.y + moveModel.y, curPosition.z + moveModel.z);50 51             //這個很重要52             yield return new WaitForFixedUpdate();53         }54     }55 }

    以上只是一個初學者自己想出來的解決方案,應該還會有更好的方法,使用座標轉換或許能行且簡單些(我沒有弄出來)。

camera旋轉+模型移動

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.