Unity3D 场景编辑器扩展学习笔记-Editor
PS:適合對UnityEditor類有一些了解的童鞋閱讀,我沒有完全研究透這套東西,暫時先學(xué)到哪寫到哪吧。
*所有的Editor相關(guān)代碼,必須存在于Assets目錄下的任意路徑的名為Editor文件夾內(nèi)。U3D會自動為這些文件生成編輯器工程。
重要的類
Editor,EditorWindow
GUILayout,EditorGUILayout
GUIUtility,EditorGUIUtility
Handles,Event
架構(gòu):Editor,EditorWindow
Editor類和EditorWindow類都繼承自同一個基類:ScriptableObject,因此他們都可以針對某種腳本類來進(jìn)行操作。
Editor類只能定制針對腳本的擴展,從腳本內(nèi)容在Inspector里的顯示布局,到變量在Scene視圖的可視化編輯
EditorWindow主要是擴展編輯器的功能,不必針對某種腳本(雖然可以做到),而且它有獨立的窗口,使用OnGUI函數(shù)來繪制2D的UI。
2D顯示:GUILayout,EditorGUILayout
GUILayout類用來繪制各種2D控件,比如按鈕,文本,可編輯文本,可折疊的列表,以及對它們的分組和排版。這些控件既可以繪制在Editor類里,也可以繪制在EditorWindow里。
EditorGUILayout類和GUILayout類似,但是提供更多的預(yù)定義控件,而且只能在Editor下才可以使用。
自定義2D控件:GUIUtility,EditorGUIUtility
GUIUtility類用來實現(xiàn)自定義的2D對象。
EditorGUIUtility類和GUIUtility類似,針對Editor下使用的GUI進(jìn)行定制。
3D顯示:Handles
Handles類提供各種場景視圖里的顯示,包括繪制線、面、扇形、方塊、圓錐、3D空間的按鈕(所謂按鈕,其實就是個響應(yīng)區(qū)域,你要是信U3D的就囧了),還有一些預(yù)定義的操作控件,比如三向箭頭,旋轉(zhuǎn)球,自由旋轉(zhuǎn)等等,這些操作針對的不是物體,而是數(shù)值,因此除了可以控制腳本對象所在的GameObject,也可以控制某些成員變量,本質(zhì)上都是在控制變量數(shù)值,因此場景擴展這個類肯定要大顯身手。
輸入:Event
Event類用來獲取輸入相關(guān)的信息,Event指的是InputEvent,包括鼠標(biāo)位置,鍵盤按下的KEYCODE,各種命令鍵(Windows的Windows鍵和Mac的Command鍵),Shift,CapsLocks之類,還有U3DEditor里的CommandName,比如 Copy,SeletecAll,Save這種菜單命令。這個信息在OnGUI,OnInspector,OnSceneGUI里都可以使用。
Editor類
使用
using UnityEditor;
[Custom(typeof(TypeName))]
class YourEditorClass : Editor
該類可以自定義對腳本類在Inspector里的視圖,重要的事件如下:
OnEnable
腳本所在對象被選中時觸發(fā),當(dāng)編輯器開始自動重新編譯時,對象會重新被選擇一次而觸發(fā)此消息。
OnDisable
腳本所在對象被取消選中時觸發(fā),當(dāng)編輯器開始自動重新編譯時,對象會重新被選擇一次而觸發(fā)此消息,腳本移除時也會觸發(fā)此消息。
OnDestroy
腳本從對象上移除時觸發(fā)
上述三個時機,適合初始化和反初始化,一些重要的對象都可以在這里獲取并緩存出來,比如 target對象(正在處理的腳本實例)等。
注意:實際測試時,并不是Disable或Destroy之后,就沒有代碼在執(zhí)行了。所以干活的代碼在引用緩存下來的變量之前,先判斷下是否為空,否則會報異常。這會影響腳本保存變量實例的值。不過這個問題很好查,只需要保證“腳本被移除時無異常,重新添加腳本時也無異常”這個測試用例就可以了。
OnInspectorGUI
定制腳本在Inspector里的顯示方式,基本上配合GUILayout可以寫出十分復(fù)雜的定制界面。有時候Inspector太小或不想和其他組件一起顯示時,可以使用EditorWindow來做這個定制界面。
OnSceneGUI
定制腳本在Scene里的表現(xiàn),比如可以將腳本內(nèi)一個怪物AI的”警戒半徑“變量,用很直觀的圓盤來表達(dá)出來,也有很多別的表現(xiàn)和操作,這些表現(xiàn)和操作都是通過GUILayout和Handles類來完成的。
OnInspectorGUI范例代碼:
using UnityEngine; using UnityEditor; using System.Collections; using System;class UIResource : MonoBehaviour { } [CustomEditor(typeof(UIResource))] class UIManifestCreator : Editor {private UIResource _script;private static bool _toggle_all = true;private GameObject _rootObject;public void OnEnable(){var script = (UIResource)(serializedObject.targetObject);if (script != null){_script = script;_rootObject = script.gameObject;}else{//這是什么情況;Console.Error.WriteLine("tell uncle kun!");}}public void OnDisable(){var script = (UIResource)(serializedObject.targetObject);if (script == null){// 這種情況是腳本對象被移除了;}else{// 這種情況是編譯腳本導(dǎo)致的重刷;}_script = null;_rootObject = null;}public void OnDestroy(){}public override void OnInspectorGUI(){GUILayout.BeginHorizontal();{if (GUILayout.Button("Save")){EditorApplication.SaveCurrentSceneIfUserWantsTo();}if (GUILayout.Button(_toggle_all ? "Untoggle All" : "Toggle All")){_toggle_all = !_toggle_all;}}GUILayout.EndHorizontal();EditorGUILayout.LabelField("", GUILayout.Width(150));Repaint();} }OnSceneGUI范例代碼: using UnityEngine; using UnityEditor; using System.Collections; using System;public class SceneTag : MonoBehaviour {public float shieldArea = 5; }[CustomEditor(typeof(SceneTag))] public class SceneEditor : Editor {void OnSceneGUI(){SceneTag scene = target as SceneTag;Handles.color = Color.blue;Handles.Label(scene.transform.position + Vector3.up * 2,scene.transform.position.ToString() + "\nShieldArea: " +scene.shieldArea.ToString());Handles.color = Color.red;Handles.DrawWireArc(scene.transform.position,scene.transform.up,-scene.transform.right,180,scene.shieldArea);scene.shieldArea =Handles.ScaleValueHandle(scene.shieldArea,scene.transform.position + scene.transform.forward * scene.shieldArea,scene.transform.rotation,1,Handles.ConeCap,1);//comment by kun 2014.2.18// GUI相關(guān)的繪制需要在Handles的繪制之后,否則會被覆蓋掉;// 使用Handles.BeginGUI會導(dǎo)致無法旋轉(zhuǎn)攝像機,原因不詳;GUILayout.BeginArea(new Rect(Screen.width - 100, Screen.height - 80, 90, 50));//Handles.BeginGUI(new Rect(Screen.width - 100, Screen.height - 80, 90, 50));try{float a = float.Parse(GUILayout.TextField(scene.shieldArea.ToString()));scene.shieldArea = a;}catch (System.Exception ex){}if (GUILayout.Button("Reset Area"))scene.shieldArea = 5;//Handles.EndGUI();GUILayout.EndArea();} }
總結(jié)
以上是生活随笔為你收集整理的Unity3D 场景编辑器扩展学习笔记-Editor的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5七夕情人节表白网页制作【生日快
- 下一篇: html头部尾部分离组件引入(JQ)