Custom Editors
加速游戲制作過程的關鍵是為哪些頻繁使用的組件創建自定義的編輯器,為了舉例,我們將會使用下面這個極其簡單的腳本進行講解,它的作用是始終保持一個對象注視某一點。
public class LookAtPoint : MonoBehaviour { public Vector3 lookAtPoint = Vector3.zero; void Update () { transform.LookAt (lookAtPoint); } }
這個腳本會讓一個對象保持面向世界空間中的某一點,讓我們做的更酷一點!
第一步是讓它在編輯器里面正常工作:即使你沒有測試游戲,也能讓這個腳本運行。我們對它添加ExecuteInEditMode屬性來做這件事。
[ExecuteInEditMode] public class LookAtPoint : MonoBehaviour { public Vector3 lookAtPoint = Vector3.zero; void Update () { transform.LookAt (lookAtPoint); } }
你可以把這個腳本加在main camera上,然后在Scene視圖中拖拽相機測試一下。
Making a Custom Editor
測試發現工作正常表現良好,但我們可以為它定制一個編輯器使其更加nice。為了實現這個目的,我們需要為它創建一個編輯器,在名為"Editor"的文件夾里面創建一個LookAtPointEditor的C#腳本。
using UnityEngine; using UnityEditor; using System.Collections; [CustomEditor(typeof(LookAtPoint))] public class LookAtPointEditor : Editor { public void OnInspectorGUI() { LookAtPoint lap = (LookAtPoint)target; lap.lookAtPoint = EditorGUILayout.Vector3Field("Look At Point", lap.lookAtPoint); if(GUI.changed) EditorUtility.SetDirty(lap); } }
這個類必須繼承Editor類。CustomEditor屬性告知Unity哪個組件需要表現為編輯器
OnInspectorGUI方法中的代碼,當Unity在Inspcetor中顯示這個編輯器時執行。你可以在這里放入任何GUI代碼--它的工作和游戲中的OnGUI方法類似,只不過它是在Inpector中執行,Editor定義了target屬性,以便讓你能夠獲得被檢視的對象。
通過檢查GUI.changed,如果發現用戶修改了任何值,EditorUtility.SetDirty代碼就會執行。其作用是將指定對象標記為臟。
[Unity內部使用dirty標記去確定資源什么時候被修改,並且需要被存盤。比如,你修改了一個prefab的MonoBehaviour或者ScriptableObject變量,你必須告訴Unity這個值被改變。Unity內置的組件,其內部在屬性變化時自動調用SetDirty方法,而像MonoBehaviour或者ScriptableObject卻不自動做這件事,所以如果你想讓變化的值能夠存儲下來,你必須要調用SetDirty方法]
在這個例子中,我們創建了一個類似於Transform編輯器中的3維向量編輯框,如下圖:
這兒還可以做更多更多,但是目前就此為止,我們還要去釣更大的魚...^~^
Scene View Additions
你可以在你自定義的編輯器中實現OnSceneGUI方法來為Scene視圖添加額外代碼。在這個例子中,我們會添加第2個位置處理器,以便讓用戶可以在Scene視圖中拖拽注視點。
using UnityEngine; using UnityEditor; using System.Collections; [CustomEditor(typeof(LookAtPoint))] public class LookAtPointEditor : Editor { public void OnInspectorGUI() { LookAtPoint lap = (LookAtPoint)target; lap.lookAtPoint = EditorGUILayout.Vector3Field("Look At Point", lap.lookAtPoint); if(GUI.changed) EditorUtility.SetDirty(lap); } public void OnSceneGUI() { LookAtPoint lap = (LookAtPoint)target; lap.lookAtPoint = Handles.PositionHandle (lap.lookAtPoint, Quaternion.identity); if(GUI.changed) EditorUtility.SetDirty(lap); }//這個沒看到什么效果,還沒太懂 }
OnSceneGUI工作就像OnInspectorGUI方法--除了它是在Scene視圖中運行。為了幫助你制作編輯接口,你可以使用Handles類中定義的方法。里面定義的所有方法都是為了在3D Scene
視圖中工作設計的。
如果你想放置2D GUI對象(GUI,EditorGUI或者其它的),你需要將他們包裝在Handles.BeginGUI()和Handles.EndGUI()中。