U3d用到的數學基礎


1. 數學(點乘/叉乘)/unity3d的數學輔助類
2. 坐標系統(本地/世界/屏幕)
3. Unity3d運行流程
4. 計算角色和目標點的夾角,旋轉角色朝向目標點,然后移動角色(例子)
5. Gizmos/inspector/地圖編輯
6. 腳本文件間的數據交互
7. Yield return/協同線程/事件
8. Socket
9. Unity3D調用c++DLL
一. Unity3d中需要的基礎數學知識(vector/matrix/transform)
看到這幾個單詞,我想在游戲引擎里面都挺常見的,unity3d里面也不例外!雖然unity給我們封裝的這么好,會用就可以了,但是知其然,還是對自己比較有幫助的。因為以后要是該用其他的引擎了呢?不想一輩子都被這些工具牽制的話,就必須理解這些可能會比較枯燥的數學知識了。當然這里面不會去討論太過復雜的數學知識,當然有興趣,可以多看點,但是不用花費他多的時間(除了想當數學家的除外),不明白的時候看一看就ok了!有了這些知識,再去看那些unity3d給我的數學輔助類,就用起來就清爽很多了!
1. 向量(vector)
向量有兩個重要的屬性長度和方向,舉例子吧!在空間里面物體移動要知道物體移動的方向和距離用向量這個數學工具就非常方便描述,還有攝像機的觀察方向、光線的走向等。
在不包含位置信息,所以它可以獨立於坐標系統。只要向量長度和方向相同就可以認為是相等的。引入坐標系統不會給向量添加額外的信息。所以向量的位置不會影響他的屬性。在討論位置和向量的時候,有一個很容易混淆的概念,就的點和向量,在unity3d中有時候用vector類描述一個點,因為vector里面有x、y、z三個float變量。Vector(x,y,z)是點還是向量,要仔細斟酌。或者我理解有誤,有知道的朋友希望告知。
單位向量和向量的模這兩個概念很基礎也很重要。具體概念我就不重復了,但是要知道這兩個向量有什么作用。單位向量可以用來表示方向,模可以用來表示距離。我門可以用這兩個概念去計算物體往哪一個方向移動,移動距離是多少。至於物體旋轉,要涉及到向量的計算,后面會提及到。
向量運算包括:加法、減法、數乘、叉積,對於運算,就不提及數學計算和概念了。百度下都知道了,大家都是有文化的人,哈哈..開玩笑了!舉例子吧!想象下你要去跟蹤一個物體移動,你發現自己的跟蹤方向有了偏差,你要怎么修正的方向呢?如果你說用眼睛,那可以,但是計算機是瞎的啊!你給計算機按個眼睛吧!計算機只會數值計算,當然你要用數學模型去表述了,然后計算啦!這時候你可以用向量減法,畫下向量減法的圖像,是不是很方便就可以解決了!再舉一個例子,你要去追擊一個物體,他總是東拐西拐的,我要速度比他快,但是方向不對的話是很難去攔截他下來的,那我要怎么辦呢?想象下向量加法的圖形,根據兩個人的速度,只要我的速度比你快,用向量加法和數乘(數乘可以用來控制速度),我就可以在路上給你按木樁,讓你撞死,守株待兔還是前途的嘛。再舉一個例子,如果我想知道目標物體,偏我的角度是多少,我可用點積,計算出我門的角度。例子還有很多,懶得舉了,不然就成舉重冠軍了,給個連接:http://wenku.baidu.com/view/f279471514791711cc79176a.html
說完向量,我想提及一個小細節,很有必要的細節。因為向量的x、y、x是float類型的。由於float的不精確,我門應該認為兩個浮點相等的可以存在一定的誤差的。我門在看到一些游戲代碼里面兩個浮點數相等可能是這樣的:
Const float EPSILON=0.001f;//誤差范圍
bool Equal(float num1,float num2)
{
//只要num1和num2在誤差范圍內,就認為相等放回真,否則放回假
Return fabs(num1-num2)<EPSILON?true:false;
}
2. 矩陣(matrix)與變換(transform)
矩陣這玩意是用來干嘛用的呢?大學老師沒告訴過我們,至於為什么不告訴我們呢?就不加討論了,反正教我的是業余的!畢竟老師沒有告訴過我,錯了希望要指正我啊!
矩陣在數學書上說是是由方程組的系數和常數組成的。從數學原理上, 矩陣代表了從一個線性空間到另一個線性空間的變換.

通過一個教科書上的例子,簡單的描述下計算公式,估計是比較笨的原因,我不喜歡直接用數學符號描述,只喜歡看圖。

矩陣說白了,個人理解就是讓你“穿越”用的,讓你的向量從一個空間轉換到另外一個空間的向量,一個位置移動(或者旋轉)到另外一個位置。至於空間有本地坐標系統,世界坐標系統,屏幕坐標系統等,以后會談及!我門看下矩陣變換有幾種:平移,旋轉,縮放,這些unity3d都已經封裝好了。想具體看下他們是怎么變換的,我懶得畫圖板畫了,去網絡上找一個圖片來!按照矩陣的算法,用向量乘以變換矩陣套下公式,比較下轉換前后的值,就知道了!
每一種變換,都有對應的變換矩陣,用向量或坐標乘以變換矩陣,即可對它們完成變換。變換矩陣之間,也可以做乘法疊加,疊加的幾何意義是把變換按疊加的先后順序復合到一個矩陣中去,注意矩陣疊加不滿**換律。變換矩陣是一個4 x 4的矩陣,所以向量和坐標需要擴展到齊次空間中。
向量:(x, y, z, 0)
坐標:(x, y, z, 1)
他們的區別在於第四項,向量的第4項取0,可以使矩陣的平移變換失效,而不影響旋轉和縮放運算。坐標第4項取1,使平移有效,並且平移變換的比例不會被變化。如果取2,則其平移的距離則是矩陣中定義的2倍。以此類推。注意,在變換后,有可能出現第4項非0/1 的情況,這個時候,我們必須要做一個映射動作,將它從齊次空間映射回3維空間,方法很簡單:
(x, y, z, w) --> (x/w, y/w, z/w, w/w) --> (x/w, y/w, z/w, 1) --> (x/w, y/w, z/w)
3. 平面(plane)與射線(Ray)
平面:
n Dot P + d = X;
X<0,點P位於平面的背面,|X| 即點P到平面的距離
X>0,點P位於平面的正面,|X| 為點P到平面的距離
射線:
設起點為P0, 方向為u,t 為參數,t 屬於 [0, 無窮大),當t 屬於(-無窮大,+無窮大)時就表示直線。
p(t) = p0 + t * u
之所以要將他們一起放一起是他們兩在實際的開發中,是常在一起使用的。至少我用的比較多,舉個例子吧!
比如我們點擊下2D的屏幕坐標,要確定游戲3D空間中位置,怎么確定呢?如何用只有x,y軸的二維鼠標,盡量精准的取得x,y,z三維空間的位置,是一個從三維出現就一直被討論的主題。即使在圖形技術如此發達的今天,三維空間的點擊仍然只能說"大概准確"。鼠標點擊來確定三維空間的位置和攝像機的關系非常大,為什么要說和攝像機有很大的關系呢?如果你熟悉Direcx3D里面的繪制流水的話,就知道攝像機把3d空間坐標轉化為屏幕坐標起着很關鍵的作用,如裁剪(clipping),投影窗口(projection window),近裁減,遠裁剪,投影平面等。寫一個段unity的代碼吧!(代碼格式調不好,就隨便看下吧)。
void Update ()
{
if(Input.GetMouseButtonDown(0))
{
RayControl();
}
if(flagMove)
{
if(Vector3.Distance(transform.position,mousePos)>1)
{
transform.Translate(transform.worldToLocalMatrix* ransform.forward* Time.deltaTime*5);//transform.forward是世界坐標,通過transform.worldToLocalMatrix轉換矩陣轉到本地坐標 然后在本地坐標運動,沒有必要必須在本地坐標系運動 但是必須注意要統一起來。
}
else
{
flagMove=false;
}
}
}
void RayControl()
{
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);//向屏幕發射一條射線(注意這個對象是主攝像機哦)
if(Physics.Raycast(ray,out hit,200))射線長度為200 和地面的碰撞盒做檢測
{
GameObject targetPos=GameObject.CreatePrimitive(PrimitiveType.Sphere);//實例化一個Sphere
targetPos.transform.localScale=new Vector3(0.5f,0.5f,0.5f);
mousePos=hit.point;//獲取碰撞點坐標
mousePos.y=transform.position.y;
targetPos.transform.position=mousePos;//Sphere放到鼠標點擊的地方
targetDir=mousePos-transform.position;//計算出朝向
Vector3 tempDir=Vector3.Cross(transform.forward,targetDir.normalized);//用叉乘判斷兩個向量 是否同方向
float dotValue=Vector3.Dot(transform.forward,targetDir.normalized);//點乘 計算兩個向量的夾角,及角色和目標點的夾角
float angle=Mathf.Acos(dotValue)*Mathf.Rad2Deg;
if(tempDir.y<0)//這塊 說明兩個向量方向相反,這個判斷用來確定 假如兩個之間夾角30度 到底是順時 還是逆時針旋轉。
{
angle=angle*(-1);
}
print(tempDir.y);
print("2:"+angle);
transform.RotateAround(transform.position,Vector3.up,angle);
flagMove=true;
}
}
注意事項:寫完了才發現 原來沒必要這么麻煩,這樣transform.forward=(mousePos-transform.position).normalized就可以直接讓角色朝向目標點 RayControl函數 好多都可以省了
4. unity3d 數學輔助類
4.1 Mathf提供數學計算的函數與常量,面有所有數學計算時需要用到的函數。Mathf對象沒有構造函數,是一個固有的對象,並不像String那樣是對象的類,因此沒有構造函數 Math()。
4.2 Matrix4x4一個標准的4x4變換矩陣一個變換矩陣可以執行任意的線形3D變換(例如,平移,旋轉,縮放,切邊等等)並且透視變換使用齊次坐標。腳本中很少使用矩陣:最常用Vector3,Quaternion,而且Transform類的功能更簡單。單純的矩陣用於特殊情況,如設置非標准相機投影。
4.3 Quaternion四元數用於表示旋轉它們基於復數的並不容易被直觀地理解,因此你沒有必要訪問或修改單個Quaternion組件(x,y,z,w);通常你只需把現有的旋轉(例如,來自Transform)並使用它們來構造新的旋轉(例如,在兩個旋轉間平滑地插值)。四元數函數你99%的時間你會使用它(其他函數僅額外使用)
Quaternion.LookRotation,Quaternion.Angle,Quaternion.Euler,Quaternion.Slerp,Quaternion.FromToRotation,Quaternion.identity。
4.4 Ray射線是一個無窮的線,開始於origin並沿着direction方向
4.5 Rect一個由x、y位置和width、height大小定義的二維矩形,Rect結構主要用於2D操作。UnityGUI系統很普遍的使用它,以及在屏幕上定位攝像機
4.6 Vector2/vector3/vector4 表示向量和點, 結構用於在Unity傳遞3D位置和方向。它也包含做些普通向量運算的函數,如角度,模,單位向量,叉乘,點乘,向前向左向右向上,插值,投影,反射,轉向……..
4.7 最后一個大總管,transform物體的位置、旋轉和縮放,場景中的每一個物體都有一個Transform。用於儲存並操控物體的位置、旋轉和縮放。每一個Transform可以有一個父級,允許你分層次應用位置、旋轉和縮放。可以在Hierarchy面板查看層次關系。他們也支持計數器(enumerator),因此你可以使用循環遍歷子物體。
原文:csdn.net


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com