unity3d 数学的数学基础和辅助类
轉載注明smartdot:http://my.oschina.net/u/243648/blog/67193
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)
向量有兩個重要的屬性長度和方向,舉樣例吧!在空間里面物體移動要知道物體移動的方向和距離用向量這個數學工具就很方便描寫敘述。還有攝像機的觀察方向、光線的走向等。
在不包括位置信息,所以它能夠獨立于坐標系統。僅僅要向量長度和方向同樣就能夠覺得是相等的。
引入坐標系統不會給向量加入額外的信息。
所以向量的位置不會影響他的屬性。
在討論位置和向量的時候,有一個非常easy混淆的概念,就的點和向量,在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維空間。方法非常easy:
(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四元數用于表示旋轉它們基于復數的并不easy被直觀地理解。因此你沒有必要訪問或改動單個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)。因此你能夠使用循環遍歷子物體。
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。
總結
以上是生活随笔為你收集整理的unity3d 数学的数学基础和辅助类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git github gitlib gi
- 下一篇: JAVA基础知识(2)--队列的操作