浅谈Unity中的rotation和Quaternion的乘法
動手寫游戲以后一個比較切身的體會,就是實際操作能檢驗很多語言的細節(jié),也許平時看API文檔,或者看一些教程的時候并沒有深刻的體會,因為大多情況下你只知道了該怎么做,卻不知道為什么要這么做,或者怎么想到這么做的,有沒有其他的作法?在項目中我要用到一個攝像機環(huán)繞的腳本,我發(fā)現(xiàn)官方Asset里已經(jīng)有這樣的一個腳本了,打開看它的代碼很簡單,區(qū)區(qū)十幾行,其中比較關鍵的一行代碼,用攝像機的rotation控制攝像機的 position,這個方法非常巧妙:
position = rotation*Vector3(0.0, 0.0, -distance) + target.position;
Unity定義Quaternion乘法重載形式有兩種:
static operator*(lhs:Quaternion, rhs:Quaternion):Quaternion static operator*(rotation:Quaternion, point:Vector3):Vector3
這兩個重載是有很大區(qū)別的,第一個是計算對一個物體旋轉lhs以后再旋轉rhs,這整個結果實際上相當于旋轉了多少,參數(shù)和返回值都是 Quaternion,也就是旋轉角度;而第二個是計算笛卡爾坐標系下某一個點,在經(jīng)過rotation的旋轉之后,會出現(xiàn)在那個位置,返回值是 Vector3.
這里target是攝像機所要環(huán)繞的物體,distance是要和它保持的距離,攝像機的位置就是算要計算出的點。昨天晚上我一直在想,這個式子為什么會成立,查了Quaternion的*號重載才看出名堂,之前看API文檔我也看到過這個,但是并沒有想到它還能有這樣的妙用。我們知道攝像機的旋轉角度,在環(huán)繞一個物體的時候,只能是左右和上下方向的旋轉,沿著縱深方向的旋轉是沒有多大意思的(也許你會覺得玩家也會喜歡上下顛倒的角度,但是在我這個項目里并不需要),所以rotation.eulerAngles必定是(x, y, 0)的形式,之前我在想為什么被轉的點要在z軸上而不是在x軸上,如果是在x軸上,那么被旋轉點是Vector3(-distance, 0, 0),旋轉方向就必須沿y軸和z軸,這和rotation只在x和y軸上有旋轉值是矛盾的。
另外一個沒有想清楚或者說沒有認真去想的問題就是,rotation的角度是怎么計算的。我之前一直認為,rotation是相對軸的旋轉角度,比如攝像機環(huán)繞腳本中,rotation的x值是相對x軸的旋轉角度,但是當這個旋轉物體運動到世界坐標系的x軸上時,rotatiion的值似乎應該為0.這樣推斷顯然rotation是相對于自身的坐標系來計算的,但是在本地坐標系來看似乎怎么旋轉x,y,z這三個值都應該是0不變,因為本地坐標系是隨著物體的旋轉一起旋轉的。
其實只要知道了Unity中rotation旋轉量的計算方式,以上問題就迎刃而解了:
Unity中rotation的類型是Quaternion,用eulerAngles屬性可以轉換成Vector3表示,我們可以把它當做一個向量,向量的計算是根據(jù)起始點和終止點的向量位置計算,但是所有的向量都有一個根據(jù)坐標系原點計算的值,這是它位置的憑據(jù),在世界坐標系下是絕對的,而前者是相對的,這兩者實際上具有某種統(tǒng)一性。參照這個計算方法,旋轉的三個坐標值就能解釋得通了。Unity把世界坐標系和本地坐標系做比較,根據(jù)本地坐標系相對于世界坐標系的偏轉計算絕對旋轉角度,根據(jù)施加rotation旋轉之前的坐標系絕對角度和之后的坐標系絕對角度計算相對旋轉角度。那么 rotation的原點在哪呢?在屬性面板里把物體的rotation屬性歸0就能看到,rotation的原點狀態(tài)就是本地坐標系和世界坐標系x,y, z三個軸方向一致的狀態(tài)。
總結
以上是生活随笔為你收集整理的浅谈Unity中的rotation和Quaternion的乘法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改elemntui tabs 下划线长
- 下一篇: WCF学习(二):契约