學前班遊戲開發入門3:Unity3D中的旋轉與引出的四元數知識

2021-01-09 clq的程式設計師學前班

我們百家號"運營"這麼一段時間以來,感覺太過具體的或者說過於專業的內容不是太受歡迎。比如前面郵件收發相減的內容,那系列在 cnblogs 可是異常火爆的,而且筆者花的心思是很多的,但在百家號中的閱讀量則很是慘澹 ... 我也不明白其中的原因啊,也許是百家號都是手機來的用戶沒有太多的時間去作達深的思考,所以經驗總結類的比較受歡迎,具體技巧的則大家就沒時間多看了。這系列的 Unity3D 也是這樣,其實這些知識對於入門來說還是很重要的,要知道 Unity3D 的坑那是一點都不少 ... ... 不過也不要緊,大家可以先大概了解一下,以後用到時記得回來仔細看就行了。

今天要說的是 Unity3D 中的旋轉,普通的旋轉在 u3d 中是相當簡單的,例如這樣:

obj.transform.Rotate(0, 0, 90);

其中的三個參數就是三維方向上的角度度數,只要學過初中的知識這些很容易就能用起來了。但在 u3d 中有一個操作非常的常見,那就是讓一個物體看向另外一個物體,比如讓攝像機一直跟著主角色。這在 u3d 中也是非常的簡單,例如:

obj.transform.LookAt(target);//看向某個物體

好了,當我們把這種方法應用到讓一個物體跟著另外一個物體走的時候就會出現奇怪的現象:這時候很可能不是物體的正面面向了另外一個物體,而是反面或者是側面面對的其他物體。這是為什麼呢?原因是因為這個 lookat 函數默認是讓物體的 z 軸對向物體,而我們要操作的這個物體很可能是從 3dmax 或者 maya 中導入的,它們的坐標軸和 u3d 的通常是不一樣的,所以很多教程在文章說會特別說明在導出模型時要先設置軸的一些參數。這個辦法當然不錯,但有時候這個模型是別人已經導出的,通過還附有別的參數,是不能重新導出軸參數的。這時候就要先計算出旋轉的參數後再繞著自身的坐標再旋轉那個軸與 u3d 軸的差值。這個算法如果要用我們高中學過的三角函數來算的話相當的繁瑣,在網上的解決方案五花八門,可惜都不是太正確,如果真要算的話,正確的代碼如下:

//obj.transform.rotation = Quaternion.LookRotation(target.transform.position - obj.transform.position, Vector3.up); //先看向目標//obj.transform.rotation = obj.transform.rotation * Quaternion.Euler(new Vector3(90, 0, 0)); //再調整自身的坐標q4 = Quaternion.LookRotation(target.transform.position - obj.transform.position, Vector3.up); //先看向目標q4 = q4 * Quaternion.Euler(new Vector3(90, 0, 0)); //再調整自身的坐標obj.transform.rotation = q4;

代碼用了兩種方向,如果直接操作物體的旋轉參數的話,那麼會看到物體動來動去顯然不行,所以要計算出兩步合成的結果後再一次性賦值給旋轉參數比較好。

而要把兩步的結果合成成一個,用三角函數算的話大家基本上算不出來吧 ... ... 也不用自卑,數字家們也曾經頭痛過很長時間,據說解決這個問題的數字家是愛爾蘭的數學家Hamilton,他用到的解決方法就是我們這次要說的4元數。也不用害怕這個沒見過的"4元數",它的意思其實只是說一個數據用4個數字表示,也不一定就用來表示角度,只不過在這裡我們特指一個旋轉的3維空間下的參數用4個浮點來表示,也就是一個角度用4個數據才能表示出來,而我們以前學的幾何中則是用3個數據就表示出來了(分別指定 x,y,z 三個軸上要旋轉的角度就可以了)。按一般的教程,這裡要狠狠地說一個4元數的各個解釋,不過我想說的是現在的軟體開發,特別是遊戲開發是應用科學,不應該也不用去細究那麼多,我們只要理解它是一個表示旋轉角度的參數就可以,然後記住操作它的那幾個函數就可以了(沒有幾個)。具體的函數大家可以再去查資料,這其中有一個方法一定要告訴大家,在 u3d 裡,兩個4元數相乘就是物體先旋轉到第一個角度然後再旋轉到第二個角度。這種用運算符號來表示某種結果的做法在 u3d 中很普遍,我個人覺得很不好,雖然用習慣了會覺得很方便,但是假如有一個沒學過的人看以上代碼肯定是不明白的,所以我覺得應該封裝成函數,不應該暴露那麼多數字的細節。類似的兩個三維空間位置相減會得到它們的向量差(例如前面的 target.transform.position - transform.position),這也是很讓初學者崩潰的。另外向量這個詞也很讓人要回憶高中數字的,其實從應用的角度來說,可以認為是用三個方向上的數值來表示的角度 -- 所以在 u3d 有多種表示角度的方法:Quaternion(四元數)、歐拉角(其實就是三個軸上分別轉動的角度)、向量(其實就是在三個方向上的長度)。這當中當然是四元數最難理解了,所以我們乾脆就不要去理解好了。

當然了,以上是學院派的做法,實際上更多的做法是先建立一個空物體,然後把模型拉成空物體的子級(見下圖),然後在設計期間在裡面旋轉調整模型的角度就可以了,而外層空物體當做正常模型來使用就可以了。讓它直接 lookat 目標就行,不用兩次代碼進行調整:

空物體做父級可輕鬆解決導出模型軸問題

大家肯定鬆了一口氣。但這還不算完,如果是操作攝像機那沒什麼好說的,如果是操作模型,直接轉向是很生硬的,通常會加上一個漸變的過程,所以具體的代碼實際上要變成正面這樣:

ship1.transform.rotation = Quaternion.Slerp(ship1.transform.rotation,Quaternion.LookRotation(target.transform.position - ship1.transform.position), //兩個位置在前後是不一樣的,原物體位置在前是最好的//還可以這樣在最後的結果上再做調整,兩個角度相乘就是角度疊加了//Quaternion.LookRotation(target.transform.position - ship1.transform.position) * Quaternion.Euler(new Vector3(90, 0, 0)), //歐拉角度轉 Quaternion, //兩個位置在前後是不一樣的,原物體位置在前是最好的//10 * Time.deltaTime);2.5f * Time.deltaTime);//速度//transform.Rotate(0, 0, 90);//ok//不行,很抖動

具體的大家可以查 Quaternion.Slerp() 函數的用法,總的來說它就是在兩個角度狀態之間根據不同的速度計算出二者的漸進值。要特別說明的是原物體的位置最好作為第一個參數,要不可能是沒有漸變平滑效果出來的。

好了,這就是我們今天要說的內容。我知道大家一定都沒聽懂,不過沒關係,大家記得需要的時候回來這裡查看就行了。

相關焦點

  • 學前班遊戲開發入門5:發射子彈與Unity3D的預設體概念
    一般的遊戲當中都有戰鬥的場景,那就免不了要讓我們控制的角色發射子彈或者是弓箭等動作。在程序中這通常是動態生成一個新的物體,然後讓它沿著一定的軌跡向前運動即可。不過在 Unity3D 中這會遇上一個非常讓初學者頭痛的事情(實際上深入使用的話也會讓老手頭痛,甚至有一個叫 "uPrefabs" 的插件專門來解決這個問題)。這個問題就是"預設體"的概念。我們先來看看通常的做法是什麼樣的,這樣才好理清頭緒。首先,這需要在場景中先建立好子彈的模型,並且關聯好各種腳本 -- 這都好理解。
  • 學前班遊戲開發入門4:Time.deltaTime與Unity3D中的長度單位
    這個 Translate 直接就是矩陣變換的意譯,使用這個函數的人還得明白在 3d 世界中移動其實就是坐標的矩陣變換 ... ... 說實在的,沒有這個必要。函數其中的參數就更不容易為初學者理解,這移動是多少呢?好吧,我直接告訴大家是米,那麼為什麼不能寫成 Translate(0, 0, 3) ,這不是移動 3 米嗎?
  • 學前班遊戲開發入門6:爆炸效果與Unity3D粒子系統入門
    通常爆炸效果由貼圖和粒子系統組成,不過貼圖顯然不是程式設計師的工作,所以我們以一個簡單的純粒子系統的實現來先入入門是很有必要的。不管是 u3d 還是別的什麼軟體,粒子系統都是異常複雜的。所以我們不可能在一篇文章中說完 u3d 中的粒子系統,我們的這個例子要通過默認的一個粒子來修改它的參數來完成爆炸的模擬。
  • 年薪30W的Unity3D遊戲開發崗面試題(上)
    當遊戲中需要頻繁創建一個物體對象時,我們需要怎麼做來節省內存。做一個pool,遊戲開始時預先實例化足夠的數量,然後用的時候取不用的時候收回22.帶的assets server功能學習遊戲開發,進入高薪行業!
  • 三維旋轉:歐拉角、四元數、旋轉矩陣、軸角之間的轉換
    2 四元數(Quaternion)與旋轉矩陣2.1 四元數---->旋轉矩陣眾所周知的是,歐拉旋轉是有萬向節死鎖(Gimbal Lock)的問題的。幸好我們有四元數(Quaternion)這種數學工具可以避免這個情況。一般來說,我們都會用單位四元數
  • 四元數與3D旋轉實例! Cocos Creator 3D Quternion !
    閱讀本文可能需要一些前置的知識(但不限於這些知識點):矩陣(平移/旋轉/縮放/模型矩陣/視圖矩陣/投影矩陣)表示3D旋轉一般採用三種方法:為什麼使用四元數表示旋轉呢?平滑插值。(矩陣基本沒有,歐拉角可以做插值,但可能遭遇萬向鎖的問題)當然四元數也有一些缺點:四元數可能不合法。(一般通過四元數標準化解決這個問題,確保四元數為單位四元數)對給定的方位的表達方式有兩種方法,它們相互為負。
  • 學前班不能成「小學化」溫床
    為了弄個究竟,賓曉亮對3所幼兒園進行了調查,並發放了問卷。這3所幼兒園中,有2所是公辦園,1所是民辦園。調查顯示,這3所幼兒園去年中班時的幼兒數分別為142、139、130,但升入大班後的幼兒數分別為98、45、108,分別流失了44人、94人、22人,流失率分別為30.99%、67.63%、16.92%。
  • 四元數簡介
    旋轉,應該是三種坐標變換——縮放、旋轉和平移,中最複雜的一種了。大家應該都聽過,有一種旋轉的表示方法叫四元數。按照我們的習慣,我們更加熟悉的是另外兩種旋轉的表示方法——矩陣旋轉和歐拉旋轉。矩陣旋轉使用了一個4*4大小的矩陣來表示繞任意軸旋轉的變換矩陣,而歐拉選擇則是按照一定的坐標軸順序(例如先x、再y、最後z)、每個軸旋轉一定角度來變換坐標或向量,它實際上是一系列坐標軸旋轉的組合。那麼,四元數又是什麼呢?簡單來說,四元數本質上是一種高階複數(聽不懂了吧。。。),是一個四維空間,相對於複數的二維空間。
  • 無人機理論(三):簡單搞定四元數
    2 四元數由來四元數是由愛爾蘭數學家Hamilton發明的,是發明的不是發現的,數學上的很多東西跟物理不一樣,它不一定是事物的發展規律,它有時候就是數學家們憑空想像出來的東西,有可能這個東西誕生以後就沒有人再用過,也有可能過了很多年,有人發現這個理論可以解釋很多現象,或者這個理論可以用來分析很多無法用現有知識解釋的現象。
  • 一文詳解四元數、歐拉角、旋轉矩陣、軸角如何相互轉換
    和被旋轉的三維向量  ,那麼要直接用四元數旋轉這個向量,則我們首先要構造一個純四元數 那麼如果這個矩陣已經是一個合法的旋轉矩陣了,要從旋轉矩陣裡提取四元數,也是可以像提取歐拉角那樣,用參數化過的矩陣的表達式湊出來。參考[8]《Real Time Rendering 3rd edition》Chapter4的思路,我們觀察一下用四元數分量進行參數化的矩陣
  • 頭條 | 一文詳解四元數、歐拉角、旋轉矩陣、軸角如何相互轉換
    和被旋轉的三維向量  ,那麼要直接用四元數旋轉這個向量,則我們首先要構造一個純四元數 那麼如果這個矩陣已經是一個合法的旋轉矩陣了,要從旋轉矩陣裡提取四元數,也是可以像提取歐拉角那樣,用參數化過的矩陣的表達式湊出來。參考[8]《Real Time Rendering 3rd edition》Chapter4的思路,我們觀察一下用四元數分量進行參數化的矩陣
  • VEX-----quaternion 四元數
    在3D程序中,通常用quaternion來計算3D物體的旋轉,可以把quaternion看做一個標量和一個3D向量的組合,在數學上,quaternion表示複數w+(xi+yj+zk),其中i,j,k都是虛數單位,實部w表示標量,虛部表示向量標記為V,或三個單獨的分量(x,y,z),所以quaternion可以記為[ w, V]或[ w,(x,y,x)]。
  • 姿態表示方法之四元數
    ~相對於複數的二維空間,為了解決三維空間的旋轉變化問題,愛爾蘭數學家 William Rowan Hamilton 把複數進行了推廣,也就是四元數。四元數由 1 個實部 和 3 個虛部構成,笛卡爾坐標下為可如下表示:
  • 剛體運動變換的描述——四元數
    一、(Eigen)四元數類型常用的四元數格式有Quaternionf(float)和Quaterniond(double),模板類中的Scalar決定數據類型。Eigen::Quaternion< _Scalar, _Options >::Quaternion( const Scalar & w,const Scalar & x,const Scalar &y,const Scalar & z )     注意:Eigen中四元數賦值的順序為
  • 遊戲開發新手入門指南
    我經常被問及:一個具有很少甚至沒有編程經驗的人要如何開始遊戲製作。直到目前為止,我總是盡我所能一個一個解答。然而,問題的數量已經增長到了一個難以處理的水平,於是,我便決定把所有的建議匯總在一篇文章裡作為參考提供給人們。   這篇文章主要面向那些想開發自己的遊戲,但僅有一點點或沒有半點編程經驗的人們。實際上,我也假定讀者根本沒有任何的編程知識。
  • 理解Unity3D中的四種坐標體系
    其實如果僅僅只有 3D 坐標系還是很簡單的,就目前來說我們所見過的三維建模軟體或者遊戲開發軟體所用的坐標系分兩種:左手坐標系和右手坐標系。怎麼區別呢?除了 3D 世界中的坐標系,還有其他的幾個坐標系也非常常用,比如我們經常要把世界三維坐標系轉換成我們最終屏幕中的二維坐標系,或者把手機屏幕的二維坐標系轉化成遊戲世界中的三維坐標系等,各個坐標系各有特別,不能混用,為了更好的學習 Unity 遊戲開發,自己在此總結一下 Unity 當中的坐標系和相關用法,以作備忘和學習。
  • 【Unity3D開發小遊戲】《跑酷小遊戲》Unity開發教程
    一、前言最近跑酷遊戲比較流行,開發教程也很多,但是大部分都是不太詳細,這篇文章就帶著大家一步一步開發出來一個跑酷類的遊戲,教程比較基礎,適合大部分
  • 入門經典 新盟曼巴蛇遊戲滑鼠售價39元
    (原標題:入門經典 新盟曼巴蛇遊戲滑鼠售價39元)
  • 2018太陽帆幼小銜接班(學前班)春季火熱招生中!!!
    我們為孩子、為您提供:     一、絕對領先的知識教育。        從太陽帆幼小銜接班畢業的往期學生,經考核,其語言、數學、拼音等成績遠遠    優於周邊幼兒園大班及其他早教機構。良好的智力開發,使太陽帆的孩子在小學的起    跑線上真正領先一步,奠定堅實的學習基礎同時,也大大的樹立了他們自信心。 二、真正的小班教學。        小班教學一直是精英教育最重要的方法之一。
  • 床長人工智慧教程免費文檔——學習Unity3D的筆記
    學習的筆記在學習時記錄的筆記的筆記中一類的警告的解決方案中沒有高級保存選項的解決方案中和的區別中關於四元數的詳解轉載自類默認方向方向的表示法①歐拉角表示法②前方上方矢量界定法③繞軸旋轉界定法④向到向相對旋轉表示法成員變量成員函數靜態函數驗證前方上方矢量表示法總結幾種表示方法將四元數旋轉應用於子彈射擊示例在學習時記錄的筆記的筆記官網地址中文官網地址