Egyéni szerkesztők

Más verziók

Nem férhet hozzá más verziókhoz offline!

A játékkészítés sebességének növeléséhez kulcsfontosságú, hogy a gyakran használt komponensekhez egyéni szerkesztőket hozzon létre. A példa kedvéért használjuk ezt a nagyon egyszerű szkriptet, amely egy objektumot mindig egy pontra néz. Add hozzá ezt a szkriptet a projektedhez, és helyezd el egy kocka gameobjectre a jelenetedben. A szkript neve legyen “LookAtPoint”

//C# Example (LookAtPoint.cs)using UnityEngine;public class LookAtPoint : MonoBehaviour{ public Vector3 lookAtPoint = Vector3.zero; void Update() { transform.LookAt(lookAtPoint); }}
//JS Example (LookAtPoint.js)#pragma strictvar lookAtPoint = Vector3.zero;function Update(){ transform.LookAt(lookAtPoint);}

Ez egy objektumot egy világtéri pont felé tart. Jelenleg ez a szkript csak játékmódban lesz aktív, vagyis amikor a játék fut. Szerkesztő szkriptek írása során gyakran hasznos, ha bizonyos szkriptek szerkesztési módban is végrehajtódnak, miközben a játék nem fut. Ezt úgy érheted el, ha hozzáadsz egy ExecuteInEditMode attribútumot:

//C# Example (LookAtPoint.cs)using UnityEngine;public class LookAtPoint : MonoBehaviour{ public Vector3 lookAtPoint = Vector3.zero; void Update() { transform.LookAt(lookAtPoint); }}
//JS Example (LookAtPoint.js)#pragma strict@script ExecuteInEditMode()var lookAtPoint = Vector3.zero;function Update(){ transform.LookAt(lookAtPoint);}

Ha mostantól kezdve, ha mozgatod az objektumot, amin ez a szkript van, a szerkesztőben, vagy megváltoztatod a “Look At Point” értékeit az inspektorban – még akkor is, ha nem játékmódban van -, az objektum ennek megfelelően frissíti a tájolását, így továbbra is a világtérben lévő célpontra néz.

Egy saját szerkesztő készítése

A fentiekben bemutattuk, hogyan lehet egyszerű szkripteket futtatni szerkesztés közben, azonban ez önmagában nem teszi lehetővé saját szerkesztőeszközök létrehozását. A következő lépés egy Custom Editor létrehozása az imént létrehozott scripthez.

Mikor a Unityben scriptet hozunk létre, az alapértelmezés szerint a MonoBehaviourtól örököl, tehát egy olyan komponens, amelyet egy játékobjektumra helyezhetünk. Amikor egy játékobjektumra helyezzük, az Inspector egy alapértelmezett felületet jelenít meg az összes megjeleníthető nyilvános változó – például egészek, lebegőszámok, karakterláncok, Vector3-ak stb. megtekintésére és szerkesztésére.

Így néz ki az alapértelmezett inspektor a fenti szkriptünkhöz:

Egy alapértelmezett inspektor egy nyilvános Vector3 mezővel

A saját szerkesztő egy különálló szkript, amely ezt az alapértelmezett elrendezést helyettesíti az Ön által választott szerkesztő vezérlőelemekkel.

A LookAtPoint szkriptünk saját szerkesztőjének létrehozásához létre kell hoznia egy másik szkriptet ugyanezzel a névvel, de a “Editor” toldalékkal. Tehát a mi példánk esetében: “LookAtPointEditor”.

//c# Example (LookAtPointEditor.cs)using UnityEngine;using UnityEditor;public class LookAtPointEditor : Editor { SerializedProperty lookAtPoint; void OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); serializedObject.ApplyModifiedProperties(); }}
//JS Example (LookAtPointEditor.js)#pragma strict@CustomEditor(LookAtPoint)@CanEditMultipleObjectsclass LookAtPointEditor extends Editor { var lookAtPoint : SerializedProperty; function OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } function OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); serializedObject.ApplyModifiedProperties(); }}

Ez az osztály az Editorból kell, hogy származzon. A CustomEditor attribútum tájékoztatja a Unity-t arról, hogy melyik komponens szerkesztőjeként kell működnie. A CanEditMultipleObjects attribútum közli a Unityvel, hogy ezzel a szerkesztővel több objektumot is ki lehet jelölni és egyszerre lehet módosítani őket.

Az OnInspectorGUI-ban található kód minden alkalommal végrehajtódik, amikor a Unity megjeleníti a szerkesztőt az Inspectorban. Ide bármilyen GUI kódot betehetsz – ugyanúgy működik, mint az OnGUI a játékoknál, de az Inspectoron belül fut. Az Editor meghatározza a céltulajdonságot, amellyel elérheti a vizsgált objektumot. Így néz ki az egyéni inspectorunk:

Nem túl érdekes, mert eddig csak annyit tettünk, hogy újra létrehoztuk a Vector3 mezőt, pontosan úgy, ahogy az alapértelmezett inspector mutatja, így az eredmény nagyon hasonlóan néz ki (bár a “Script” mező most nincs jelen, mert nem adtunk hozzá semmilyen inspector kódot a megjelenítéséhez).

Most azonban, amikor már rendelkezhetünk az ellenőr megjelenítésének módjával egy Editor scriptben, tetszőleges kódot használhatunk az ellenőr mezőinek elrendezéséhez, lehetővé téve a felhasználó számára az értékek beállítását, és akár grafikákat vagy más vizuális elemeket is megjeleníthetünk. Valójában a Unity Editorban látható összes ellenőr, beleértve az összetettebb ellenőröket, mint például a tereprendszer és az animációimport-beállítások, mind ugyanazt az API-t használják, amelyhez hozzáférhetsz, amikor saját egyéni szerkesztőket hozol létre.

Itt egy egyszerű példa, amely kibővíti a szerkesztő szkriptjét, hogy megjelenítsen egy üzenetet, amely jelzi, hogy a célpont a játékobjektum felett vagy alatt van-e:

//c# Example (LookAtPointEditor.cs)using UnityEngine;using UnityEditor;public class LookAtPointEditor : Editor{ SerializedProperty lookAtPoint; void OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); serializedObject.ApplyModifiedProperties(); if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Above this object)"); } if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Below this object)"); } }}
//JS Example (LookAtPointEditor.js)#pragma strict@CustomEditor(LookAtPoint)@CanEditMultipleObjectsclass LookAtPointEditor extends Editor { var lookAtPoint : SerializedProperty; function OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } function OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); serializedObject.ApplyModifiedProperties(); if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Above this object)"); } if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Below this object)"); } }}

Így most már van egy új elem az ellenőrünkben, amely kiír egy üzenetet, amely megmutatja, hogy a célpont a játékobjektum felett vagy alatt van-e.

Ez csak a felszínét karcolja annak, amit a szerkesztő szkriptekkel tehet. Teljes hozzáférésed van az összes IMGUI parancshoz, hogy bármilyen típusú felületet megrajzolhass, beleértve a jelenetek renderelését a szerkesztőablakokon belüli kamerával.

Scene View Additions

Egy OnSceneGUI implementálásával az egyéni szerkesztődben extra kódot adhatsz a Scene View-hoz.

Az OnSceneGUI ugyanúgy működik, mint az OnInspectorGUI – azzal a különbséggel, hogy a jelenetnézetben fut le. A saját szerkesztővezérlők jelenetnézetben történő elkészítéséhez a Handles osztályban definiált függvényeket használhatja. Az ott található összes függvény a 3D Scene nézetekben való munkavégzésre készült.

//C# Example (LookAtPointEditor.cs)using UnityEngine;using UnityEditor;public class LookAtPointEditor : Editor{ SerializedProperty lookAtPoint; void OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); if (lookAtPoint.vector3Value.y > (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Above this object)"); } if (lookAtPoint.vector3Value.y < (target as LookAtPoint).transform.position.y) { EditorGUILayout.LabelField("(Below this object)"); } serializedObject.ApplyModifiedProperties(); } public void OnSceneGUI() { var t = (target as LookAtPoint); EditorGUI.BeginChangeCheck(); Vector3 pos = Handles.PositionHandle(t.lookAtPoint, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Move point"); t.lookAtPoint = pos; t.Update(); } }}
//JS Example (LookAtPointEditor.js)#pragma strict@CustomEditor(LookAtPointJS)@CanEditMultipleObjectsclass LookAtPointEditorJS extends Editor { var lookAtPoint : SerializedProperty; function OnEnable() { lookAtPoint = serializedObject.FindProperty("lookAtPoint"); } function OnInspectorGUI() { serializedObject.Update(); EditorGUILayout.PropertyField(lookAtPoint); serializedObject.ApplyModifiedProperties(); if (lookAtPoint.vector3Value.y > (target as LookAtPointJS).transform.position.y) { EditorGUILayout.LabelField("(Above this object)"); } if (lookAtPoint.vector3Value.y < (target as LookAtPointJS).transform.position.y) { EditorGUILayout.LabelField("(Below this object)"); } } function OnSceneGUI() { var t : LookAtPointJS = (target as LookAtPointJS); EditorGUI.BeginChangeCheck(); var pos = Handles.PositionHandle(t.lookAtPoint, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Move point"); t.lookAtPoint = pos; t.Update(); } }}

Ha 2D GUI objektumokat (GUI, EditorGUI és barátai) szeretne elhelyezni, akkor azokat a Handles.BeginGUI() és Handles.EndGUI() hívásokba kell csomagolnia.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.