Editori personalizați

Alte versiuni

Nu puteți accesa alte versiuni offline!

O cheie pentru creșterea vitezei de creare a jocurilor este crearea de editori personalizați pentru componentele utilizate în mod obișnuit. De dragul exemplului, vom folosi acest script foarte simplu care menține întotdeauna un obiect în căutarea unui punct. Adăugați acest script în proiectul dvs. și plasați-l pe un obiect de joc cub în scena dvs. Scriptul ar trebui să se numească „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);}

Aceasta va menține un obiect orientat spre un punct din spațiul mondial. În prezent, acest script va deveni activ doar în modul de joc, adică atunci când jocul este în desfășurare. Atunci când se scriu scripturi de editor, este adesea util ca anumite scripturi să se execute și în timpul modului de editare, în timp ce jocul nu rulează. Puteți face acest lucru adăugându-i un atribut ExecuteInEditMode:

//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);}

Acum, dacă deplasați obiectul care are acest script în editor sau modificați valorile „Look At Point” din inspector – chiar și atunci când nu este în modul de joc – obiectul își va actualiza orientarea în mod corespunzător, astfel încât să rămână cu privirea spre punctul țintă din spațiul mondial.

Crearea unui editor personalizat

Cele de mai sus demonstrează modul în care puteți face să ruleze scripturi simple în timpul editării, însă numai acest lucru nu vă permite să vă creați propriile instrumente de editare. Următorul pas este de a crea un editor personalizat pentru scriptul pe care tocmai l-am creat.

Când creați un script în Unity, în mod implicit acesta moștenește din MonoBehaviour și, prin urmare, este o componentă care poate fi plasată pe un obiect de joc. Atunci când este plasat pe un obiect de joc, inspectorul afișează o interfață implicită pentru vizualizarea și editarea tuturor variabilelor publice care pot fi afișate – cum ar fi numere întregi, flotante, șiruri de caractere, Vector3, etc.

Iată cum arată inspectorul implicit pentru scriptul nostru de mai sus:

Un inspector implicit cu un câmp public Vector3

Un editor personalizat este un script separat care înlocuiește acest aspect implicit cu orice control al editorului pe care îl alegeți.

Pentru a începe crearea editorului personalizat pentru scriptul nostru LookAtPoint, ar trebui să creați un alt script cu același nume, dar cu „Editor” adăugat. Deci, pentru exemplul nostru: „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(); }}

Această clasă trebuie să derive din Editor. Atributul CustomEditor informează Unity pentru care componentă ar trebui să acționeze ca editor. Atributul CanEditMultipleObjects îi spune lui Unity că puteți selecta mai multe obiecte cu acest editor și le puteți modifica pe toate în același timp.

Codul din OnInspectorGUI este executat ori de câte ori Unity afișează editorul în Inspector. Puteți pune orice cod GUI aici – funcționează la fel ca OnGUI pentru jocuri, dar este executat în interiorul Inspectorului. Editor definește proprietatea țintă pe care o puteți utiliza pentru a accesa obiectul care este inspectat. Iată cum arată inspectorul nostru personalizat:

Nu este foarte interesant, deoarece tot ce am făcut până acum a fost să recreăm câmpul Vector3, exact așa cum ne arată inspectorul implicit, deci rezultatul arată foarte asemănător (deși câmpul „Script” nu este acum prezent, deoarece nu am adăugat niciun cod de inspector pentru a-l afișa).

Cu toate acestea, acum că aveți controlul asupra modului în care este afișat inspectorul într-un script Editor, puteți folosi orice cod doriți pentru a aranja câmpurile inspectorului, pentru a permite utilizatorului să ajusteze valorile și chiar pentru a afișa grafice sau alte elemente vizuale. De fapt, toți inspectorii pe care îi vedeți în Unity Editor, inclusiv inspectorii mai complecși, cum ar fi sistemul de teren și setările de import al animațiilor, sunt toți realizați cu ajutorul aceluiași API la care aveți acces atunci când vă creați propriii Editori personalizați.

Iată un exemplu simplu care extinde scriptul editorului dumneavoastră pentru a afișa un mesaj care să indice dacă punctul țintă este deasupra sau sub obiectul jocului:

//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)"); } }}

Acum avem un nou element la inspectorul nostru care tipărește un mesaj care arată dacă punctul țintă este deasupra sau sub obiectul jocului.

Aceasta este doar o zgârietură la suprafața a ceea ce puteți face cu scripturile Editorului. Aveți acces complet la toate comenzile IMGUI pentru a desena orice tip de interfață, inclusiv redarea scenelor folosind o cameră în interiorul ferestrelor editorului.

Scene View Additions

Puteți adăuga cod suplimentar la Scene View prin implementarea unui OnSceneGUI în editorul dumneavoastră personalizat.

OnSceneGUI funcționează la fel ca OnInspectorGUI – cu excepția faptului că se execută în vizualizarea scenei. Pentru a vă ajuta să vă realizați propriile controale de editare în vizualizarea scenei, puteți utiliza funcțiile definite în clasa Handles. Toate funcțiile de acolo sunt concepute pentru a lucra în vizualizări de scenă 3D.

//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(); } }}

Dacă doriți să puneți obiecte GUI 2D (GUI, EditorGUI și prietenii), trebuie să le înfășurați în apeluri la Handles.BeginGUI() și Handles.EndGUI().

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.