Custom Editors

Other Versions

Cannannot access other versions offline!

Een sleutel tot het verhogen van de snelheid van het maken van spellen is het maken van custom editors voor veelgebruikte componenten. Om een voorbeeld te geven, zullen we dit zeer eenvoudige script gebruiken dat een object altijd naar een punt laat kijken. Voeg dit script toe aan je project, en plaats het op een kubus gameobject in je scene. Het script moet de naam “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);}

krijgen. Dit zal een object gericht houden op een punt in de wereld-ruimte. Momenteel wordt dit script alleen actief in speelmodus, dat wil zeggen, als het spel draait. Bij het schrijven van editor scripts is het vaak handig om bepaalde scripts ook in edit mode uit te laten voeren, terwijl het spel niet draait. Je kunt dit doen door er een ExecuteInEditMode attribuut aan toe te voegen:

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

Als je nu het object met dit script in de editor verplaatst, of de waarden van “Look At Point” in de inspector verandert – zelfs als het niet in de speelstand staat – zal het object zijn oriëntatie overeenkomstig aanpassen, zodat het blijft kijken naar het doelpunt in de wereldruimte.

Een aangepaste editor maken

Het bovenstaande demonstreert hoe je eenvoudige scripts kunt laten draaien tijdens bewerkingstijd, maar dit alleen stelt je niet in staat om je eigen editor gereedschappen te maken. De volgende stap is het maken van een aangepaste editor voor het script dat we zojuist hebben gemaakt.

Wanneer je een script maakt in Unity, erft het standaard van MonoBehaviour, en is daarom een Component dat op een spelobject kan worden geplaatst. Wanneer het op een spelobject wordt geplaatst, toont de Inspector een standaardinterface voor het bekijken en bewerken van alle openbare variabelen die kunnen worden getoond – zoals gehele getallen, zwevende waarden, tekenreeksen, Vector3’s, enz.

Zo ziet de standaard-inspector er voor ons bovenstaande script uit:

Een standaard-inspector met een openbaar Vector3-veld

Een aangepaste editor is een apart script dat deze standaardindeling vervangt door editorbesturingselementen die u zelf kiest.

Om te beginnen met het maken van de aangepaste editor voor ons LookAtPoint-script, moet u een ander script maken met dezelfde naam, maar met “Editor” toegevoegd. Dus voor ons voorbeeld: “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(); }}

Deze klasse moet van Editor afstammen. Het CustomEditor attribuut informeert Unity voor welke component het als editor moet fungeren. Het CanEditMultipleObjects attribuut vertelt Unity dat je met deze editor meerdere objecten kunt selecteren en ze allemaal tegelijk kunt wijzigen.

De code in OnInspectorGUI wordt uitgevoerd wanneer Unity de editor in de Inspector weergeeft. Je kunt hier elke GUI-code in stoppen – het werkt net als OnGUI doet voor spellen, maar wordt uitgevoerd in de Inspector. Editor definieert de target eigenschap die je kunt gebruiken om toegang te krijgen tot het object dat geïnspecteerd wordt. Hier ziet onze aangepaste inspector eruit:

Het is niet erg interessant, want alles wat we tot nu toe hebben gedaan is het Vector3-veld opnieuw maken, precies zoals de standaard inspector ons laat zien, dus het resultaat lijkt er sterk op (hoewel het “Script”-veld nu niet aanwezig is, omdat we geen inspectorcode hebben toegevoegd om het te tonen).

Maar nu u de controle heeft over hoe de inspector wordt weergegeven in een Editor script, kunt u elke code gebruiken die u maar wilt om de inspector velden op te maken, de gebruiker in staat te stellen de waarden aan te passen, en zelfs afbeeldingen of andere visuele elementen weer te geven. In feite zijn alle inspectors die je ziet in de Unity Editor, inclusief de meer complexe inspectors zoals het terreinsysteem en animatie import instellingen, allemaal gemaakt met dezelfde API waar je toegang tot hebt als je je eigen aangepaste editors maakt.

Hier volgt een eenvoudig voorbeeld dat je editor script uitbreidt om een bericht weer te geven dat aangeeft of het doelpunt zich boven of onder het gameobject bevindt:

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

Dus nu hebben we een nieuw element in onze inspector dat een bericht weergeeft dat aangeeft of het doelpunt zich boven of onder het gameobject bevindt.

Dit is slechts een tipje van de sluier van wat je kunt doen met Editor scripting. Je hebt volledige toegang tot alle IMGUI-commando’s om elk type interface te tekenen, inclusief het renderen van scènes met behulp van een camera binnen editorvensters.

Scèneweergave-toevoegingen

Je kunt extra code toevoegen aan de Scèneweergave door een OnSceneGUI in je aangepaste editor te implementeren.

OnSceneGUI werkt net als OnInspectorGUI – behalve dat het wordt uitgevoerd in de scene view. Om u te helpen uw eigen bewerkingscontroles in de scène te maken, kunt u de functies gebruiken die zijn gedefinieerd in de klasse Handles. Alle functies daarin zijn ontworpen voor het werken in 3D Scene views.

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

Als je 2D GUI objecten (GUI, EditorGUI en vrienden) wilt plaatsen, moet je ze verpakken in calls naar Handles.BeginGUI() en Handles.EndGUI().

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.