51.Inspector調試模式
在Inspector面板右上角的下拉菜單中,選擇Debug命令,啟動調試模式,此時將顯示組件包含的所有變量,包括私有變量,當運行編輯器時,可以實時查看各組件所有變量的變化。
52.高亮顯示Debug.Log對應的游戲對象
當使用Debug.Log方法輸出信息時,可將gameObject作為此方法的第二個參數,當程序運行時,點擊Console面板中對應的輸出信息,可在Hierarchy面板中高亮顯示掛載了此腳本的游戲對象。
void Start() { Debug.Log("this is a message",gameObject); }
53.風格化Debug.Log的輸出信息
當Debug.Log方法的輸出消息是字符串時,可以使用富文本標記來強調內容。如下代碼所示:
Debug.Log("<color=red>Fatal error:</color> AssetBundle not found");
輸出效果:
54.繪制調試數據
當變量隨着時間的推進而改變時,可使用AnimationCurve實例在程序運行時繪制此數據,如下代碼所示:
public AnimationCurve plot = new AnimationCurve(); void Update() { float value = Mathf.Sin(Time.time); plot.AddKey(Time.realtimeSinceStartup, value); }
返回Unity編輯器,運行程序,點擊plot屬性,此時會隨着時間動態繪制數據的變化情況,如下圖所示:
55.快速新建腳本並掛載到游戲對象上
選擇游戲對象,在Inspector面板上點擊Add Component按鈕,在搜索框中輸入新建的腳本名稱並回車,可新建腳本並掛載到目標游戲對象上,雙擊腳本名稱進行腳本編寫。
56.導入第三方項目文件
Unity能夠讀取部分第三方創作工具保存的項目文件,比如Photoshop的PSD,Blender的源文件等,不需要從這些軟件導出中轉文件格式,比如Jpg、FBX等。
57.導入后保留PSD文件的圖層結構
將PSD文件另存為PSB格式,將其導入Unity后可保留文件圖層結構,此時需要在Package Manager中安裝2D PSD Importer,並且在文件的導入屬性中設置Texture Type 為Sprite (2D and UI)。
58+59.為游戲對象指定/自定義圖標
點擊游戲對象Inspector面板左上角的下拉菜單,可為游戲對象指定一個特定顏色的標識,這對空游戲對象的可視化也比較有用。點擊Other...按鈕,可以用自己的圖片來進行標識。
60/61.顯示/隱藏Gizmo
點擊Scene面板右上角的Gizmo下拉列表,可以選擇顯示或隱藏某類組件的圖標和Gizmo標識;也可點擊Game面板右上角的Gizmo按鈕,顯示或隱藏所有資源的圖標和Gizmo。
62.字符串拼接
可使用StringBuilder進行字符串的拼接,不要使用字符串相加的形式,因為這樣會帶來額外的內存垃圾。如下代碼所示:
StringBuilder myStr = new StringBuilder(); myStr.Append("Hello").Append("The").Append("World");
不建議:
string myStr = "Hello" + "the" + "world";
使用StringBuilder需要引用命名空間System.Text。
63.使用ScriptableObjects管理游戲數據
對於游戲數據比如武器、成就等,可使用ScriptableObjects在編輯器中進行有效組織。如下代碼所示:
using UnityEngine; [CreateAssetMenu(fileName = "New Item", menuName = "Item")] public class NewBehaviourScript : ScriptableObject { public string ItemName; public int ItemLevel; public Texture2D ItemIcon; }
64.編輯器播放時修改腳本后的處理
選擇 Edit > Preferences > General 命令,在Script Changes While Playing中,可以設置編輯器在播放狀態下如果腳本發生改變后的處理,比如停止播放重新編譯等。
65.自定義窗口
將類繼承自EditorWindow,可以添加自定義窗口,在此基礎上編寫一些命令和工具,如下代碼所示:
using UnityEngine; using UnityEditor; public class ExampleWindow : EditorWindow { [MenuItem("Window/Example")] public static void ShowWindow() { GetWindow<ExampleWindow>("Example"); } }
執行效果:
66.自定義Inspector
也可對Inspector進行自定義,添加一些控件。如下代碼所示:
using UnityEngine; using UnityEditor; [CustomEditor(typeof(Sphere))] public class SphereEditor : Editor { public override void OnInspectorGUI() { GUILayout.Label("自定義Inspector"); GUILayout.Button("確定"); } }
執行效果:
67.工具快捷鍵
使用快捷鍵Q、W、E、R、T、Y切換移動、旋轉、縮放等工具。
68.使用RectTransform工具縮放3D物體
RectTransform工具一般用於縮放2D物體,對3D物體使用該工具可以在某個二維平面對其進行縮放,這取決於物體與視口的關系。
69+70+71.吸附
按下Ctrl鍵對游戲對象進行移動、旋轉、縮放,將以步進的形式進行操作,選擇Editor > Snap Settings...命令,可設置步進大小。
按下V鍵,在游戲對象上選擇頂點進行拖放,將以此頂點為基礎,把游戲對象吸附到其它頂點的位置。
72. 管理程序集
在Project面板中選擇Create > Assembly Definition 命令,創建程序集文件,然后將其拖放到指定的文件夾中,定義腳本依賴關系,可以確保腳本更改后,只會重新生成必需的程序集,從而減少編譯時間。
73.WaitForSecondsRealtime
當時間縮放為0時(即Time.timeScale=0f),waitForSeconds方法將不會停止等待,后續代碼也不會執行,此時可使用WaitForSecondsRealtime方法,如下代碼所示:
Time.timeScale = 0f; yield return new WaitForSecondsRealtime(1f);
74+75.緩存組件引用
當某組件需要被頻繁訪問時,可在初始化時預先獲取該組件的引用,從而避免在訪問時由於重復獲取引起的性能開銷。
private Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); } void Update() { rb.AddForce(0f, -2f, 0f); }
同樣的情況,也不要在使用Camera.main獲取攝像機組件,尤其避免使用類似以下方法:
Camera cam = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
這樣會帶來更大的性能消耗。
76.字符串性能優化
如果某字符串在整個應用過程中不會改變且被頻繁使用,可將其存儲在靜態只讀變量中,從而節省內存分配,如下代碼所示:
static readonly string Fire1 = "Fire1"; void Update() { Input.GetAxis(Fire1); }
不建議:
void Update() { Input.GetAxis("Fire1"); }
77/78/79/80.方便使用的元數據
為變量添加一些屬性可使它們在Inspector面板中更容易被使用。在變量前添加Range屬性可將其限定在某個范圍內使用滑塊進行調節,如下代碼所示:
[Range(0f,10f)] public float speed = 1f;
執行效果:
兩個變量聲明之間加入[Space]可在Inspector中添加一個空行;添加Header可在Inspector面板中加入一段文字,如下代碼所示:
[Header("Player Settings")] public float speed = 1f; public int size = 10;
執行效果:
在變量前加入Tooltip,當鼠標懸停在Inspector面板中的變量上時,可顯示關於此變量的說明,如下代碼所示:
[Tooltip("移動速度")] public float speed = 1f;
執行效果:
82.合並場景
在Project面板中,將一個場景文件拖到另外一個上,可將場景進行合並。
83/84.創建游戲對象/數組元素副本快捷鍵
選擇一個游戲對象,使用快捷鍵Ctrl+D可快速創建該游戲對象的副本,同樣的方法可創建數組元素的副本。
85.組件預設
當完成某個組件的屬性設置后,可點擊組件右上角的預設按鈕,將當前屬性設置保存為預設,方便后續進行組件設置時使用。
86.遍歷游戲對象所有子物體
可使用foreach循環遍歷游戲對象的所有子物體,如下代碼所示:
foreach (Transform child in transform) { Debug.Log(child.name); }
87.通過腳本改變游戲對象在Hierarchy中的順序
使用transform.SetSiblingIndex方法可以設置游戲對象在Hierarchy面板中的順序,如下代碼所示:
transform.SetSiblingIndex(1);
以上代碼實現在游戲運行時,設置游戲對象在Hierarchy面板中的順序為同級節點中的第二個。
88.保存選擇狀態
當選擇了多個游戲對象后,可在 Edit > Selection 的子菜單中選擇一個Save Selection項,暫存當前選擇狀態。選擇Load Selection+對應的序號,即可恢復某個選擇狀態。此方法對跨節點選擇多個對象的情況非常適用,這樣將不必依次展開節點重新進行查找選擇。
89.#region 和 #endregion
使用#region 和 #endregion可以將兩者之間包含的代碼折疊,方便閱讀。
90.通過腳本暫定編輯器播放
使用EditorApplication.isPaused可通過代碼在編輯器播放時將其暫停,如下代碼所示:
void Update() { if (Time.time >= 10f) { EditorApplication.isPaused = true; } }
需要引用命名空間UnityEditor。
91.逐幀查看程序運行
點擊暫停按鈕右側的步進(Step)按鈕,可以在程序運行時逐幀查看程序運行狀態。
92/93/94.查看游戲性能統計
點擊Game窗口右上角的Stats按鈕可以查看游戲性能統計數據,如幀率、批處理等指標。
查看更加詳細的分析數據,可使用Window > Analysis > Profiler工具;使用Profiler.BeginSample和Profiler.EndSample方法可在Profiler中查看函數的資源使用情況,如下代碼所示:
Profiler.BeginSample("expensive"); CalculateSomething(); Profiler.EndSample();
需要引入UnityEngine.Profiling命名空間。
95.彈出預覽窗口
通常情況下,項目資源在Inspector面板底部均有一個預覽窗口。鼠標右鍵點擊預覽窗口頂部,可將該窗口彈出,作為獨立窗口,放置在編輯器的任意位置。
96.測試游戲時靜音
點擊Game窗口右上角的Mute Audio按鈕,可在編輯器播放時將所有聲音關閉。
97.InvokeRepeating方法
InvokeRepeating能夠按照一定的時間間隔反復執行某個函數,若不使用CancelInvoke方法,InvokeRepeating將持續執行,即使將方法所在的腳本關閉。
98.Frame Debugger
使用Frame Debugger(Window > Analysis > Frame Debugger)可以查看每一幀的渲染過程。
99.Physics Debugger
使用Physics Debugger(Window > Analysis > Physics Debugger)可以查看碰撞引起的異常,當開啟Collision Geometry選項后,場景中所有游戲對象的碰撞體都將被繪制出來,而不用依次選擇游戲對象進行檢查。如下圖所示,球體因為添加了不正確的Box Collider,在物理碰撞時必然不能達到預期的表現效果。