Unity3D腳本基礎
Mono和IL2CPP
Unity的腳本后端我們可以選擇使用Mono或者IL2CPP,可以到player setting中進行更改選擇
Mono
Mono是Xamarin公司的開源項目,是基於CLI通用語言架構以及C#的ECMA標准的.NET框架另外一種實現,可以分為四個部分:C#編譯器 mcs、Mono運行時、基礎類庫、Mono類庫
C# 編譯器 mcs
mcs是自Mono2.11版本之后的統一編譯器,因為mcs是使用C#編寫的編譯器,使用了很多.Net API,所以在使用mcs時需要Mono運行時來運行mcs,在win平台可以使用微軟的.Net運行時,也可以使用Mono運行時
Mono運行時
Mono運行時實現了ECMA的通用語言架構標准,定義了.NEt框架基礎結構的可執行代碼以及代碼的運行時環境,提供了一個JIT編譯器、一個AOT編譯器,同時還有類庫加載器、GC、線程系統等
基礎類庫
Mono提供了廣泛的基礎類庫並且與微軟的.Net框架兼容
Mono類庫
Mono還提供了超越.Net框架之外的諸多類
使用Mono腳本后端的編譯過程:
我們用C#編寫的游戲邏輯會通過Mono mcs編譯器編譯成的IL中間語言byte code,之后,Mono運行時中的JIT或者AOT編譯器將IL中間語言byte code轉譯為本地代碼Native Code
- JIT編譯器
JIT,即時編譯或者稱動態編譯,是指在程序執行時才編譯代碼,解釋一條語句執行一條語句,即翻譯一條中間語言成機器代碼,然后執行該條機器代碼,Android的Dalvik虛擬機就是使用的JIT編譯,而IOS平台則不允許這樣的動態編譯
- AOT編譯器
代碼在程序運行之前就已經編譯好了,不過在AOT中部分代碼也會通過JIT方式來動態編譯,在IOS平台上Unity會使用Full AOT來進行編譯,集中所有的IL中間代碼不適用JIT,直接進行AOT編譯生成一個本地代碼鏡像,在運行時直接加載鏡像
IL2CPP
IL2CPP包含兩部分,一個AOT編譯器,一個用來支持虛擬機的運行時庫
IL2CPP AOT編譯器
IL2CPP AOT編譯器用於將IL中間語言轉換為C++代碼,其可執行文件的名字叫做il2cpp.exe,可以在Unity的安裝目錄Editor\Data\il2cpp下找到,il2cpp.exe是一個托管代碼可執行文件,是由C#編寫
使用IL2CPP腳本后端編譯的過程:
我們使用C#編寫的游戲邏輯會通過Unity自帶的Mono mcs編譯器編譯成的IL中間語言,IL和其他程序集一起組成托管程序集
無用代碼的剝離,來減小構建游戲的大小,包括托管代碼的剝離、原生代碼的剝離
-
托管代碼的剝離,UnityLinker會通過中間語言移除掉沒有使用的類型(未使用的類、結構體等,包括已使用類,但是並沒使用的類的方法),可以在Player Setting中的Stripping Level選項選擇Strip Assemblies開啟,需要注意的是,這個選項只有在使用Mono腳本后端可選,在使用IL2CPP時是默認開啟的
-
原生代碼剝離,移除原生的Unity引擎代碼中未使用的模塊和類,可以在Player Setting中Strip Engine Code選項選擇開啟,禁用的話會保留原生Unity引擎代碼中所有的模塊和類
il2cpp.exe將剝離之后的托管程序集轉換成標准C++代碼,之后再傳遞給最終的目標平台對應的編譯器編譯生成的C++代碼和IL2CPP的運行庫,最終根據目標平台將代碼鏈接到Dll或者可執行文件中。
IL2CPP 運行時庫
IL2CPP 運行時庫用於支持IL2CPP虛擬機的運行,提供如GC、線程等支持,運行庫的名字叫做libil2cpp,該運行時庫最終其會作為一個靜態庫鏈接到用戶可執行應用中,這樣做的好處是簡單可移植
Unity3D中的引用類型
UnityEngine.Object類
在Unity3D的腳本系統中,Unity使用命名空間UnityEngine來盛放Unity3D定義的類型;
其中UnityEngine.Object類是最基本的類,是在Unity3D中所有對象的基類;
所有派生自UnityEngine.Object類的公共變量都會被顯示在監視面板中,Unity程序員可通過編輯器來修改這些變量的數值。
UnityEngine.Object類提供的類成員:
字段:
- hideFlags:標識該游戲對象是否被隱藏
- name
公共方法:
- GetInstanceID
- ToString:返回該游戲對象的名稱
靜態方法:
- Destory
- DestoryImmediate
- DontDestoryOnLoad
- FindObjectOfType
- FindObjectsOfType
- Instance
UnityEngine.Component類
除了最基本的UnityEngine類之外,另一個很重要的類是派生自UnityEngine.Object類的UnityEngine.Component類。它是所有能添加到游戲對象GameObject上的組件Component的基類。
UnityEngine.Component類提供的類成員:
字段:
- gameObejct:該組件所在的游戲對象
- tag:該組件所在游戲對象的標簽
- transform:該組件所在游戲對象上的Transform組件
公共方法:
- BroadcastMessage
- CompareTag:返回該對象是否被標簽標記
- GetComponent
- GetComponentInChildren
- GetComponentInParent
- GetComponents
- GetComponentsInChildren
- GetComponentsInParent
- SendMessage
- SendMessageUpwards
UnityEngine.Behaviour類
UnityEngine.Behaviour類繼承自UnityEngine.Component類,
是一個可以啟用或者禁用的組件
UnityEngine.Behaviour類提供的類成員:
變量:
- enable:啟用狀態下,會執行每幀的更新,禁用狀態不會被執行
- isActiveAndEnable:表示當前Behaviour是否被啟用
UnityEngine.MonoBehaviour類
UnityEngine.MonoBehaviour繼承自UnityEngine.Behaviour類;在Unity3D游戲引擎中,UnityEngine.MonoBehaviour類是所有Unity3D腳本的基類。
UnityEngine.MonoBehaviour類提供的類成員:
消息:
- Awake
- Start
- Update
- LateUpdate
- FixedUpdate
- OnEnable
- OnDisable
- OnDestory
- OnBecameInvisible
- OnBecameVisible
- OnCollisionEnter
- OnCollsionExit
- OnCollisionStay
- OnGUI
- OnLevelWasLoaded
- OnMouseDown
- OnMouseDrag
- OnMouseEnter
- OnMouseExit
- OnMouseOver
- OnMouseUp
- OnMouseUpAsButton
- OnTriggerEnter
- OnTriggerExit
- OnTriggerStay
- OnValidate
- Reset
公共方法:
- CancelInvoke
- Invoke
- InvokeRepeating
- IsInvoking
- StartCoroutine
- StopAllCoroutine
- StopCoroutine
Unity3D腳本編程時需要注意,在C#中使用new操作符來實例化引用類型,但是在Unity3D中編寫腳本時,凡是繼承自MonoBehaviour類的類型包括MonoBehaviour本身都無法使用new關鍵字來進行實例化;
在Unity3D中我們可以通過將腳本以組件的形式掛載在游戲對象上來實現創建類型對象的目的。
當然,不需要繼承自MonoBehaviour類的類型,是可以通過new操作符實例化的。
Unity3D中的值類型
向量結構
Vector2、Vector3、Vector4這三個結構體分別用來表示二維、三維、四維向量。
向量結構的實例成員:
- magnitude
- normalized
- sqrMagnitude
- x
- y
- z
- w
向量結構的方法:
- Cross
- Dot
- Distance
- Lerp
向量計算
向量之間的乘法與標量之間的乘法不同,向量的乘法常用的有兩種
- 點乘dot product(或者稱點積、內積inner product)
- 叉乘cross product(或者稱叉積、外積outer product)
向量之間的點乘
向量a(ax,ay,az)與向量b(bx,by,bz)為示例
向量點乘公式一:
將兩個三位向量的對應分量相乘后求和就是這兩個向量點乘的結果為一個標量
a·b = axbx + ayby + azbz
向量點乘的幾何意義
即我們可以通過兩個向量點積結果的符號來判斷兩個向量方向的關系
a·b > 0時,兩個向量方向相同
a·b = 0時,兩個向量相互垂直
a·b < 0時,兩個向量方向相反
向量a與向量b,點乘的結果可以看作,向量b在向量a所處單位向量方向上的投影長度乘以向量a的模
向量點乘的一些性質
(k a)·b = a·(k b) = k(a·b) k為標量
a·(b+c) = a·b + a·c 減法同理
a·a = axax + ayay + azaz = |a|2 可以利用點積來求一個向量的模或者直接比較兩個向量與自身的點積a·a與b·b的大小
向量點乘公式二:
當兩個向量都是單位向量時:
單位向量a與單位向量b點乘的結果為它們夾角的余弦乘以|b|,即夾角余弦值
由此,可推導出向量a與向量點乘的公式為:
a·b = |a||b|cos<a,b>
向量之間的叉乘
a X b =(ax,ay,az) X (bx,by,bz)
=(aybz-azby, azbx-axbz,axby-aybx)
向量叉乘的結果是一個新的向量,該新向量的模為,向量a與向量b模的乘積再乘以他們之間夾角的正弦值:
|a X b| = |a||b|sin<a,b>
新向量的方向根據我們使用的左手坐標系或者右手坐標系確定
當兩個向量平行即方向相同或者相反時,叉乘結果為零向量:
a X b = 0
其他值類型
- Color
- Color32
- Ray
- Touch
- RaycastHit
- Bounds
- Rect
- Plane
REF
書籍:
Unity3D腳本編程
博客:
https://blogs.unity3d.com/2015/05/06/an-introduction-to-ilcpp-internals/