遇到一個想作的功能,可是實現不了,核心緣由是由於對U3D的3D數學概念沒有靈活吃透。故再次系統學習之—第三次學習3D數學.程序員
本次,但願實現的功能很簡單:ide
如在小地圖中,但願能夠動態畫出Player當前的位置、z的朝向:用3條線、z軸正向、30°旋轉、-30°旋轉。函數
問題是:0點能夠得到,P1點? P2點是未知的。源碼分析
我嘗試了2個小時,結果不竟如人意,少於沮喪。學習
不得不,再次花點時間系統的學習3D數學:動畫
點: 點和向量在數學上是一致的,實際生活中點的概念比較好理解,座標點來定位–南二環、北二環。 【點用(3,4,5)圓括號來標示,簡稱P】this
向量:「俗稱增量」,有大小和方向,如」往前1步走。 左轉90度」. 往前走,直到碰到牆,你纔會停下來—在這以前,你沒法準確得到碰到牆的點的座標或者你和牆的距離。 【向量用<3,4,5>尖括號來標示,簡稱V】spa
在U3D中,統一用Vector3對象來表達向量和點,這個也是致使新手暈頭轉向的一個很重要的緣由; 一個技巧,凡是在API中用position、Point的,V3確定表明是點;凡是Vector、direction的是向量;多看官方的API手冊,寫得很明白。pwa
作個遊戲,列表出你用過的Vector3的API,分析分析用到的Vector3是向量(V)仍是點(P)3d
需求 |
API |
向量(V) 點(P) |
備註 |
平滑位移 |
Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta); |
P |
|
平滑位移 |
Vector3 Slerp(Vector3 from, Vector3 to, float t) |
P |
|
新的座標點 |
this.m_transform.position = pos; |
P |
符合常規思惟 |
變更一次座標 |
m_transform.Translate(new Vector3(rx, 0, -m_Speed * Time.deltaTime)); |
V |
可認爲是增量 |
求方向 |
Vector3 relativePos = this.m_transform.position – m_Player.position; |
V |
向量減法,較難理解 |
設置新座標點 |
lineRenderer.SetPosition(0,this.gameObject.transform.position); m_NavAgent.SetDestination(this.m_Player.transform.position); |
P |
符合常規思惟 |
新的位置 |
pointer.transform.position = hitInfo.point + (transform.position – hitInfo.point) * 0.01f; |
P、V |
力的疊加? |
求距離 |
float dis = Vector3.Distance(v1, v2); float f1 = (v1 – v2).sqrMagnitude; float f3 = (v1 – v2).magnitude; |
P、V |
Distance用點便可 向量減法也能夠 |
縮放正向 |
Vector3 v3 = this.m_transform.forward * 200f; |
V |
V的數乘 |
射線檢測 |
Ray r = new Ray(source, dest); Physics.Raycast(r, out hit, 1000, m_ShootMask) |
V、P |
Source:P Dest:V |
加一個力 |
rigidbody.AddForce (0, 10, 0); |
V |
依據這個遊戲,能夠整理出目前用到的有4個組件(含Vector 3)會發生位移:
位移經常使用的4個組件和Vector3:
組件 |
函數 |
Unity 聖典的API說明 |
是否 用過 |
transform組件 |
translate函數 |
向某方向移動物體多少距離【默認local座標系】 或者相對某物體移動 |
yes |
Position屬性 |
在世界空間座標transform的位置 |
Yes |
|
RigidBody組件 [FixedUpdate函數] |
Velocity屬性 |
剛體的速度向量 Unity 官方demo Done用的很酷 |
Yes |
AddForce函數 |
添加一個力到剛體。做爲結果剛體將開始移動。 |
yes |
|
MovePosition函數 |
移動剛體到position |
||
NavMeshAgent組件 |
SetDestination函數 |
設置自動Path目標點 |
yes |
CharacterController 組件 |
Move函數 |
一個更加複雜的運動函數,每次都絕對運動 |
yes |
SimpleMove函數 |
以必定的速度移動角色 |
||
Vector3向量 |
Lerp函數 |
兩個向量之間的線性插值。 「像彈簧一個跟隨目標物體」 |
|
Slerp函數 |
球形插值在兩個向量之間 「在日出和日落之間動畫弧線」 |
||
MoveToward函數 |
當前的地點移向目標 和Vector3.Lerp相同,maxDistanceDelta限速 |
||
SmoothDamp 函數 |
隨着時間的推移,逐漸改變一個向量朝向預期的目標。 |
個人幾個向量相關的問題:
如何判斷A向量和B向量是否同方向?
如何判斷A向量和B向量前、後、左、右?
如何判斷A向量和B向量的夾角?
向量的減法貌似比加法更有用一些?
Vector.Forward和this.transform.Forward都表達local座標系,那麼數值爲何不同呢?
旋轉在3D中是比較複雜的,在Unity 3D中通常用Quaternion來進行旋轉, 旋轉僅涉及向量的概念(向量的方向),請思考對於座標點或者零向量旋轉有無心義?
而按照Unity 3D API官方的說法,僅有約7個方法或者操做符比較經常使用,且佔99%的機率,我截止目前尚未用到這麼多,我用到的Quaterniong約有4個函數。
旋轉經常使用7個API:
Quaternion API |
Unity 聖典的API說明 |
是否 用過 |
Quaternion.LookRotation |
建立一個旋轉,沿着forward(z軸)而且頭部沿着upwards(y軸)的約束注視。也就是創建一個旋轉,使z軸朝向y軸朝向up。 經常使用的是transform.LookAt |
yes |
Quaternion.Angle |
返回a和b二者之間的角度。 |
|
Quaternion.Euler |
返回一個旋轉角度,繞z軸旋轉z度,繞x軸旋轉x度,繞y軸旋轉y度(像這樣的順序)。 |
yes |
Quaternion.Slerp |
球形插值,經過t值from向to之間插值。 |
|
Quaternion.FromToRotation |
從fromDirection到toDirection建立一個旋轉。 |
|
Quaternion.identity |
返回恆等式旋轉(只讀)。這個四元數對於「無旋轉」:這個物體徹底對齊於世界或父軸。 |
yes |
Quaternion.operator * |
由另外一個四元數來旋轉一個旋轉角度,或由一個旋轉角度來旋轉一個向量 |
yes |
個人幾個旋轉相關的問題:
1 Quaternion.LookRotation和Vector3.RotateTowards的區別?
2 Quaternion.Angle和Vector3.Angle的區別?
3 Quaternion.LookRotation和transform.LookAt的區別?
[官方回答: 大多數時間你可使用transform.LookAt代替
Quaternion.LookRotation]
4 如何實現2個GameObject face to face,即Z軸相對?
磨刀不誤砍柴工: 通過一週的複習、反覆驗證,果真在系統學習3D 數學後,要實現的功能能夠了,以下:
參考博客:
座標系的簡介:C#程序員整理的Unity 3D筆記(八):Unity 3D座標系介紹
宣雨鬆的博客:http://www.xuanyusong.com/archives/1977
總結:
聽說80%、90%Unity 3D程序員是自學的,大多數是看看書、實戰視頻、源碼分析;而科班出生的同窗會有3D數學這門核心課–估計佔一個學期、會有做業等。爲了遇上科班同窗的水平,花點時間,補補數學知識,會使得本身少走一些彎路。一句話:」3D數學模型很關鍵。「