轉載註明smartdot:http://my.oschina.net/u/243648/blog/67193 html
1. 數學(點乘/叉乘)/unity3d的數學輔助類c++
2. 座標系統(本地/世界/屏幕)算法
3. Unity3d執行流程數組
4. 計算角色和目標點的夾角。旋轉角色朝向目標點,而後移動角色(樣例)網絡
5. Gizmos/inspector/地圖編輯ide
6. 腳本文件間的數據交互函數
7. Yield return/協同線程/事件工具
8. Socketspa
9. Unity3D調用c++DLL.net
---------------------------------------------------------------
---------------------------------------------------------------
一. 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)。所以你可以使用循環遍歷子物體。