Hinzufügen eigener Tools zum Editor von Unity

In diesem Lernprogramm erfahren Sie, wie Sie den Unity3D-Editor erweitern, um ihn in Ihrem Projekt besser einsetzen zu können. Sie lernen, wie Sie ein eigenes Gizmo zeichnen, Objekte im Code erstellen und löschen, Editorfenster erstellen, Komponenten verwenden und dem Benutzer die Möglichkeit geben, alle mit Ihrem Skript durchgeführten Aktionen rückgängig zu machen.

In diesem Lernprogramm wird vorausgesetzt, dass Sie bereits die Grundlagen des Unity-Workflows kennen. Wenn Sie wissen, wie Sie Objekte, Prefabs, Szenen erstellen, sich im Editor bewegen, Komponenten anhängen, können Sie loslegen!


Endergebnisvorschau

Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:

Wie Sie sehen, erstellen wir ein Editorfenster und eine Farbauswahl, deren Auswahl wir zum Zeichnen eines Gitters verwenden. Wir können auch Objekte erstellen und löschen, an diesem Raster ausrichten und diese Aktionen rückgängig machen.


Schritt 1: Gizmos

Zuerst lernen wir, wie man Gizmos benutzt. Hier sind ein paar Beispiele für eingebaute Gizmos.

Dies ist derjenige, den Sie wahrscheinlich am meisten in Unity sehen werden, da er für jedes Objekt gezeichnet wird, das ein Verwandeln Eine Komponente ist damit verbunden - im Grunde wird jedes Gizmo dieses Gizmo gezeichnet.

Hier ist ein weiteres Gizmo, mit dem wir die Größe des sehen können BoxCollider an unserem Spielobjekt befestigt.


Schritt 2: Erstellen Sie ein Rasterskript

Erstellen Sie ein C # -Skript, mit dem wir unser eigenes Gizmo für ein Objekt zeichnen können. Als Beispiel zeichnen wir ein einfaches Raster im Editor.

mit UnityEngine; using System.Collections; öffentliche Klasse Grid: MonoBehaviour void Start ()  void Update () 

Für ein Gitter müssen wir zwei Variablen hinzufügen, die Breite und die Höhe.

public class Grid: MonoBehaviour public float width = 32.0f; Höhe des öffentlichen Schwimmers = 32.0f; void Start ()  void Update () 

Um im Editor zu zeichnen, müssen wir verwenden OnDrawGizmos Rückruf, also lass es uns erstellen.

public class Grid: MonoBehaviour public float width = 32.0f; Höhe des öffentlichen Schwimmers = 32.0f; void Start ()  void Update ()  void OnDrawGizmos () 

Schritt 3: Zeichnen Sie das Raster

Um ein Raster zu zeichnen, benötigen wir eine Reihe von horizontalen und vertikalen Linien sowie die Position der Kamera des Editors, damit wir wissen, um welchen Punkt wir unser Raster zeichnen sollen. Zuerst speichern wir die Position der Kamera in einer separaten Variablen.

void OnDrawGizmos () Vector3 pos = Camera.current.transform.position; 

Wie Sie sehen, können Sie die Kamera des Editors mit der Kamera-Strom Referenz.

Jetzt brauchen wir zwei for-Schleifen, die die horizontale und vertikale Linie zeichnen.

void OnDrawGizmos () Vector3 pos = Camera.current.transform.position; für (float y = pos.y - 800.0f; y < pos.y + 800.0f; y+= height)  Gizmos.DrawLine(new Vector3(-1000000.0f, Mathf.Floor(y/height) * height, 0.0f), new Vector3(1000000.0f, Mathf.Floor(y/height) * height, 0.0f));  for (float x = pos.x - 1200.0f; x < pos.x + 1200.0f; x+= width)  Gizmos.DrawLine(new Vector3(Mathf.Floor(x/width) * width, -1000000.0f, 0.0f), new Vector3(Mathf.Floor(x/width) * width, 1000000.0f, 0.0f));  

Zum Zeichnen von Linien verwenden wir Gizmos.DrawLine (). Notiere dass der Gizmos In class gibt es viele andere API-Methoden zum Zeichnen. Daher ist es möglich, Primitive wie Würfel oder Kugeln oder sogar deren Drahtmodelle zu zeichnen. Bei Bedarf können Sie auch ein Bild zeichnen.

Die Rasterlinien sollten aber unendlich lang sein float.positiveInfinity und float.negativeInfinity Mit dem Zeichnen der Linien schien es nicht gut zu funktionieren, also können wir stattdessen einfach beliebig große Zahlen verwenden. Außerdem hängt die Anzahl der Zeilen strikt von den Konstanten ab, die wir in einfügen zum Definitionen der Schleifen; Technisch sollten wir diese Konstanten nicht lassen, aber es ist nur ein Testcode.

Um das Raster zu sehen, erstellen Sie ein leeres Objekt und hängen Sie unser Skript daran an:


Schritt 4: Erstellen Sie einen benutzerdefinierten Inspektor

Als Nächstes müssen Sie den Inspektor anpassen. Dazu müssen wir ein Editor-Skript erstellen. Erstellen Sie eine neue C # -Datei und benennen Sie sie GridEditor. Dieses Skript sollte in der Editor Mappe; Wenn Sie noch keine haben, erstellen Sie sie jetzt.

mit UnityEngine; UnityEditor verwenden; using System.Collections; [CustomEditor (typeof (Grid))] öffentliche Klasse GridEditor: Editor 

Dieses Mal müssen wir auch verwenden UnityEditor die Klassen und Funktionen des Editors nutzen zu können. Um den Standardinspektor unseres zu überschreiben Gitter object müssen wir vor unserer Klassendeklaration ein Attribut hinzufügen, [CustomEditor (typeof (Grid))] lässt Unity wissen, dass wir das anpassen werden GitterInspektor. Um die Editor-Callbacks nutzen zu können, müssen wir aus dem Editor Klasse statt MonoBehaviour.

Um den aktuellen Inspektor zu ändern, müssen Sie den alten Inspektor überschreiben.

öffentliche Klasse GridEditor: Editor public override void OnInspectorGUI () 

Wenn Sie den Inspektor des Rasterobjekts jetzt im Editor überprüfen, ist er leer, obwohl das Objekt selbst einige öffentliche Mitglieder hat. Das liegt daran, dass durch das Überschreiben der OnInspectorGUI () Wir haben den Standardinspektor verworfen, um stattdessen einen benutzerdefinierten zu erstellen.


Schritt 5: Füllen Sie den benutzerdefinierten Inspektor mit GUILayout

Bevor wir Felder erstellen, müssen wir einen Verweis auf das Objekt erhalten, für das der Inspektor gilt. Wir haben bereits eine Referenz - es heißt Ziel - Der Einfachheit halber erstellen wir einen Verweis auf die Gitter Bestandteil dieses Objekts. Lassen Sie uns es zuerst erklären.

öffentliche Klasse GridEditor: Editor Gitterraster;

Wir sollten es in zuweisen OnEnable () Funktion, die aufgerufen wird, sobald der Inspektor aktiviert ist.

öffentliche Klasse GridEditor: Editor Gitterraster; public void OnEnable () grid = (grid) Ziel; 

Lassen Sie uns jetzt einige Inspektorfelder erstellen. Dafür verwenden wir die Klassen GUILayout und EditorGUILayout.

public override void OnInspectorGUI () GUILayout.BeginHorizontal (); GUILayout.Label ("Gitterbreite"); grid.width = EditorGUILayout.FloatField (grid.width, GUILayout.Width (50)); GUILayout.EndHorizontal (); 

Die erste Zeile, GUILayout.BeginHorizontal (); zeigt an, dass wir die folgenden Inspektor-Elemente von links nach rechts nebeneinander platzieren möchten. Wie Sie sich vielleicht vorstellen können, die letzte Zeile, GUILayout.EndHorizontal (); zeigt an, dass wir das nicht mehr machen wollen. Die tatsächlichen Elemente befinden sich zwischen diesen beiden Zeilen. Das erste ist ein einfaches Etikett (in unserem Fall wird es angezeigt Gitterbreite text) und daneben erstellen wir eine EditorGUILayout.FloatField Welches ist, wie Sie sich ein Floatfeld vorstellen können. Beachten Sie, dass wir zuweisen Gitterbreite auf den Wert davon FloatField, und das Float-Feld selbst zeigt den Wert von Gitterbreite. Wir setzen auch seine Breite auf 50 Pixel.

Mal sehen, ob das Feld zum Inspektor hinzugefügt wird:


Schritt 6: Füllen Sie den Inspector und streichen Sie die Szene neu

Jetzt fügen wir dem Inspektor ein weiteres Element hinzu. diesmal wird es sein Rasterhöhe.

public override void OnInspectorGUI () GUILayout.BeginHorizontal (); GUILayout.Label ("Gitterbreite"); grid.width = EditorGUILayout.FloatField (grid.width, GUILayout.Width (50)); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Rasterhöhe"); grid.height = EditorGUILayout.FloatField (grid.height, GUILayout.Width (50)); GUILayout.EndHorizontal (); 

Das wäre alles für unsere Rasterobjektfelder. Wenn Sie mehr über andere Felder und Elemente erfahren möchten, die Sie im Inspektor verwenden können, besuchen Sie die Unity-Referenzseiten in EditorGUILayout und GUILayout.

Beachten Sie, dass die Änderungen, die wir in unserem neuen Inspektor vornehmen, nur sichtbar sind, nachdem wir das Szenenansicht-Fenster ausgewählt haben. Um sie sichtbar zu machen, können wir sie anrufen SceneView.RepaintAll ().

public override void OnInspectorGUI () GUILayout.BeginHorizontal (); GUILayout.Label ("Gitterbreite"); grid.width = EditorGUILayout.FloatField (grid.width, GUILayout.Width (50)); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Rasterhöhe"); grid.height = EditorGUILayout.FloatField (grid.height, GUILayout.Width (50)); GUILayout.EndHorizontal (); SceneView.RepaintAll (); 

Jetzt müssen wir nicht außerhalb des Inspektors klicken, um die Ergebnisse der Änderungen zu sehen.


Schritt 7: Bearbeiten Sie die Editor-Eingabe

Versuchen wir nun, die Eingabe des Editors so zu handhaben, wie wir es im Spiel tun würden. Alle Tasten- oder Mauszustände sollten uns zur Verfügung stehen. Um diese Funktionalität zu haben, müssen Sie eine hinzufügen onSceneGUIDelegate Rückruf an unsere SceneView. Rufen wir unsere Update-Funktion auf GridUpdate ().

public void OnEnable () grid = (grid) Ziel; SceneView.onSceneGUIDelegate = GridUpdate;  void GridUpdate (SceneView-Szenenansicht) 

Jetzt brauchen wir nur noch die Eingabe Veranstaltung.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; 

Schritt 8: Erstellen Sie ein Prefab

Um mit den Editor-Skripten weiter spielen zu können, benötigen wir ein Spielobjekt, das wir verwenden können. Lassen Sie uns einen einfachen Würfel erstellen und daraus ein Prefab machen.

Sie können die Größe des Gitters an den Würfel oder umgekehrt anpassen und an einem Gitter ausrichten.

Wie Sie sehen, wird in der Hierarchieansicht die Würfel Text ist blau gefärbt; Dies bedeutet, dass es mit einem Fertigteil verbunden ist. Sie können dieses Prefab im Projektfenster sehen.


Schritt 9: Erstellen Sie ein Objekt aus dem Editor-Skript

Jetzt erstellen wir ein Objekt aus dem Editor-Skript. Gehen wir zu unserem zurück GridEditor.cs und erweitern die GridUpdate () Funktion.

Lassen Sie uns das Objekt beim Schlüssel erstellen ein wird gedrückt.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; if (e.isKey && e.character == 'a') GameObject obj; 

Wie Sie sehen, prüfen wir einfach, ob es sich bei dem Ereignis um eine Statusänderung handelt und ob das gedrückte Zeichen 'ist.ein'. Wir erstellen auch eine Referenz für unser neues Objekt. Lassen Sie uns es jetzt instanziieren.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; if (e.isKey && e.character == 'a') GameObject obj; if (Selection.activeObject) obj = (GameObject) Instanziieren (Selection.activeObject); obj.transform.position = new Vector3 (0.0f, 0.0f, 0.0f); 

Selection.activeObject ist eine Referenz auf das aktuell ausgewählte Objekt im Editor. Wenn ein Objekt ausgewählt ist, klonen wir es einfach und ändern die Position des Klons in (0,0, 0,0, 0,0).

Lassen Sie uns testen, ob es funktioniert. Sie müssen auf eines bedacht sein: unser GridUpdate () funktioniert nicht mehr, wenn die Assets neu importiert / aktualisiert werden. Um sie erneut zu aktivieren, müssen Sie das Objekt auswählen (z. B. aus der Hierarchieansicht), auf das sich das Editorskript bezieht Gitter Objekt. Sie müssen auch beachten, dass die Eingabeereignisse nur erfasst werden, wenn die Szenenansicht ausgewählt ist.


Schritt 10: Instanziieren Sie ein Prefab aus dem Editor-Skript

Obwohl es uns gelungen ist, das Objekt zu klonen, ist die Verknüpfung des geklonten Objekts zum Prefab nicht vorhanden.

Wie Sie sehen können, die Würfel (Klon) Der Name wird mit einer einfachen schwarzen Schrift angezeigt. Dies bedeutet, dass er nicht mit dem Prefab verbunden ist, da der ursprüngliche Cube vorhanden ist. Wenn wir den ursprünglichen Cube manuell im Editor duplizieren, wird der geklonte Cube mit dem Würfel verknüpft Würfel vorgefertigt Damit es für uns so funktioniert, müssen wir es nutzen InstantiatePrefab () Funktion von EditorUtility Klasse.

Bevor wir diese Funktion verwenden, müssen wir das Prefab des ausgewählten Objekts ermitteln. Um das zu tun, müssen wir verwenden GetPrefabParent () das gehört auch zum EditorUtility Klasse.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; if (e.isKey && e.character == 'a') GameObject obj; Object prefab = EditorUtility.GetPrefabParent (Selection.activeObject); if (vorgefertigt) 

Wir können auch aufhören zu prüfen, ob die Selection.activeObject existiert, denn wenn nicht, dann vorgefertigt wird gleich sein Null, und deshalb können wir nur mit der Prüfung davonkommen vorgefertigt Referenz.

Lassen Sie uns jetzt unser Fertigteil instanziieren und seine Position festlegen.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; if (e.isKey && e.character == 'a') GameObject obj; Object prefab = EditorUtility.GetPrefabParent (Selection.activeObject); if (vorgefertigt) obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); obj.transform.position = new Vector3 (0.0f, 0.0f, 0.0f); 

Und das ist es - lass uns prüfen, ob der geklonte Cube jetzt mit dem Prefab verbunden ist.


Schritt 11: Übersetzen Sie Screen Mouse Coords in World Coords

Das Veranstaltung class teilt uns nicht mit, wo sich die Maus im Weltraum befindet, sie liefert nur die Mauskoordinaten des Bildschirmbereichs. So konvertieren wir sie, um eine angenäherte Position der Weltraummaus zu erhalten.

void GridUpdate (SceneView-Szenenansicht) Ereignis e = Event.current; Ray r = Camera.current.ScreenPointToRay (neuer Vector3 (e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight)); Vector3 mousePos = r.origin;

Zuerst benutzen wir die Kamera des Editors ScreenPointToRay Um den Strahl von den Bildschirmkoordinaten zu erhalten, müssen wir leider den Bildschirmbereich des Ereignisses in einen für diesen Bereich akzeptablen Bereich übersetzen ScreenPointToRay ().

e.mousePosition hält die Mausposition in einem Koordinatenraum, in dem sich die obere linke Ecke befindet (0, 0) Punkt und rechte untere Ecke ist gleich (Camera.current.pixelWidth, -Camera.current.pixelHeight). Wir müssen es in den Raum übersetzen, wo die Unterseite linke Ecke ist die (0, 0) und oben rechts ist (Camera.current.pixelWidth, Camera.current.pixelHeight), Das ist ziemlich einfach.

Als nächstes sollten wir den Ursprung des Strahls für uns speichern mousePos Vektor, so ist es leicht zugänglich.

Jetzt können wir die Position des Klons der Position der Maus zuweisen.

if (vorgefertigt) obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); obj.transform.position = neuer Vector3 (mousePos.x, mousePos.y, 0.0f); 

Wenn die Kamera wirklich flach eingestellt ist, ist die Annäherung der Mausposition auf einer der Achsen wirklich sehr schlecht, deshalb habe ich die Einstellung vorgenommen z Position des Klons manuell. Jetzt sollten die Würfel erstellt werden, wo auch immer sich die Maus befindet.


Schritt 12: Richten Sie die Würfel am Raster aus

Da wir unser Raster eingerichtet haben, wäre es eine Schande, es nicht zu benutzen. Verwenden Sie unsere Mausposition, um die erstellten Würfel am Raster auszurichten.

if (vorgefertigt) obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); Vector3 ausgerichtet = neu Vector3 (Mathf.Floor (mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor (mousePos.y / grid.height) * grid.height + grid.height / 2,0 f, 0,0 f); obj.transform.position = ausgerichtet; 

Schauen Sie sich das Ergebnis an:


Schritt 13: Zerstören Sie ein Objekt aus dem Editor-Skript

In diesem Schritt löschen wir Objekte programmgesteuert im Editor. Das können wir mit tun DestroyImmediate (). In diesem Beispiel nutzen wir die Auswahl klassifizieren und löschen Sie alle ausgewählten Objekte, wennd'Taste wird gedrückt.

if (e.isKey && e.character == 'a') GameObject obj; Object prefab = EditorUtility.GetPrefabParent (Selection.activeObject); if (vorgefertigt) obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); Vector3 ausgerichtet = neu Vector3 (Mathf.Floor (mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor (mousePos.y / grid.height) * grid.height + grid.height / 2,0 f, 0,0 f); obj.transform.position = ausgerichtet;  else if (e.isKey && e.character == 'd') foreach (GameObject obj in Selection.gameObjects) DestroyImmediate (obj); 

Wenn der 'd'Taste wird gedrückt, wir durchlaufen alle ausgewählten Objekte und löschen alle Objekte. Natürlich könnten wir auch drücken Löschen Drücken Sie im Editor die Taste, um diese Objekte zu löschen. Diese werden jedoch nicht von unserem Skript gelöscht. Testen Sie es im Editor.


Schritt 14: Objektinstanzierung rückgängig machen

In diesem Schritt verwenden wir die Rückgängig machen Klasse, die uns grundsätzlich jede Aktion rückgängig machen kann, die unser Editor-Skript ausführt. Beginnen wir damit, die Objekterstellung rückgängig zu machen.

Um ein Objekt, das wir im Editor erstellt haben, zu zerstören, müssen wir es aufrufen Rückgängig machen.RegisterCreatedObjectUndo (). Es gibt zwei Argumente: Das erste ist das Objekt, das erstellt wurde, und das zweite ist der Name des Rückgängigmachens. Der Name der Aktion, die rückgängig gemacht werden soll, wird immer unter angezeigt Bearbeiten-> Rückgängig Name.

if (vorgefertigt) obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); Vector3 ausgerichtet = neu Vector3 (Mathf.Floor (mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor (mousePos.y / grid.height) * grid.height + grid.height / 2,0 f, 0,0 f); obj.transform.position = ausgerichtet; Undo.RegisterCreatedObjectUndo (obj, "Create" + obj.name); 

Wenn Sie ein paar Würfel mit dem erstellen ein Schlüssel und versuchen Sie es jetzt rückgängig zu machen, und Sie werden feststellen, dass alle erstellten Cubes gelöscht wurden. Das liegt daran, dass alle diese erstellten Cubes in ein einzelnes Undo-Ereignis eingingen.


Schritt 15: Einzelobjekt-Instantiierung rückgängig machen

Wenn wir jedes erstellte Objekt in ein anderes Rückgängig-Ereignis einfügen möchten, und das rückgängige Erstellen eines Objekts rückgängig machen möchten, müssen wir es verwenden Undo.IncrementCurrentEventIndex ().

if (prefab) Undo.IncrementCurrentEventIndex (); obj = (GameObject) EditorUtility.InstantiatePrefab (vorgefertigt); Vector3 ausgerichtet = neu Vector3 (Mathf.Floor (mousePos.x / grid.width) * grid.width + grid.width / 2.0f, Mathf.Floor (mousePos.y / grid.height) * grid.height + grid.height / 2,0 f, 0,0 f); obj.transform.position = ausgerichtet; Undo.RegisterCreatedObjectUndo (obj, "Create" + obj.name); 

Wenn Sie das Skript jetzt testen, werden Sie feststellen, dass die Würfel nacheinander gelöscht werden, indem Sie deren Erstellung rückgängig machen.


Schritt 16: Löschen von Objekten rückgängig machen

Um das Löschen des Objekts rückgängig zu machen, müssen wir es verwenden Rückgängig machen.RegisterSceneUndo (). Dies ist eine sehr langsame Funktion, die im Wesentlichen den Szenenstatus speichert, sodass wir später durch eine Rückgängig-Aktion zu diesem Status zurückkehren können. Leider scheint es momentan die einzige Möglichkeit zu sein, die gelöschten Objekte wieder in Szene zu setzen.

else if (e.isKey && e.character == 'd') Undo.IncrementCurrentEventIndex (); Undo.RegisterSceneUndo ("Ausgewählte Objekte löschen"); foreach (GameObject obj in Selection.gameObjects) DestroyImmediate (obj); 

Rückgängig machen.RegisterSceneUndo () braucht nur ein Argument, und das ist der Name des Undos. Nach dem Löschen einiger Würfel mit der d Taste können Sie das Löschen rückgängig machen.


Schritt 17: Erstellen Sie ein Editorfensterskript

Erstellen Sie ein neues Skript, und erweitern Sie dieses EditorWindow anstatt Editor. Nennen wir es GridWindow.cs.

mit UnityEngine; UnityEditor verwenden; using System.Collections; öffentliche Klasse GridWindow: EditorWindow public void Init () 

Lassen Sie uns einen Verweis auf unsere erstellen Gitter Objekt, so dass wir vom Fenster aus darauf zugreifen können.

öffentliche Klasse GridWindow: EditorWindow Grid grid; public void Init () grid = (Grid) FindObjectOfType (typeof (Grid)); 

Jetzt müssen wir das Fenster erstellen, wir können das von unserem Fenster aus machen GridEditor Skript.


Schritt 18: Erstellen Sie das GridWindow

In unserer OnInspectorGUI () Lassen Sie uns einen Button hinzufügen, der das erstellt GridWindow.

public override void OnInspectorGUI () GUILayout.BeginHorizontal (); GUILayout.Label ("Gitterbreite"); grid.width = EditorGUILayout.FloatField (grid.width, GUILayout.Width (50)); GUILayout.EndHorizontal (); GUILayout.BeginHorizontal (); GUILayout.Label ("Rasterhöhe"); grid.height = EditorGUILayout.FloatField (grid.height, GUILayout.Width (50)); GUILayout.EndHorizontal (); if (GUILayout.Button ("Gitterfenster öffnen", GUILayout.Width (255))) Fenster GridWindow = (GridWindow) EditorWindow.GetWindow (typeof (GridWindow)); window.Init ();  SceneView.RepaintAll (); 

Wir gebrauchen GUILayout Um eine Schaltfläche zu erstellen, legen wir auch den Namen und die Breite der Schaltfläche fest. Das GUILayout.Button kehrt zurück wahr Wenn der Knopf gedrückt wird, öffnen wir unseren, wenn dies der Fall ist GridWindow.

Sie können zum Editor zurückkehren und den Button in unserem drücken Gitter Objektinspektor.

Sobald Sie das tun, die GridWindow sollte auftauchen.


Schritt 19: Erstellen Sie ein Farbfeld im GridWindow

Bevor wir etwas in unserem Fenster bearbeiten, fügen wir in unserem Fenster ein Farbfeld hinzu Gitter Klasse, so können wir es später bearbeiten.

public class Grid: MonoBehaviour public float width = 32.0f; Höhe des öffentlichen Schwimmers = 32.0f; öffentliche Farbe Farbe = Farbe.weiß;

Nun ordnen Sie die Gizmos.color in dem OnDrawGizmos () Funktion.

void OnDrawGizmos () Vector3 pos = Camera.current.transform.position; Gizmos.color = Farbe;

Und jetzt gehen wir zurück zu GridWindow Skript und erstellen Sie dort ein Farbfeld, damit wir die Farbe im Fenster auswählen können. Das können wir im tun OnGUI () Ruf zurück.

öffentliche Klasse GridWindow: EditorWindow Grid grid; public void Init () grid = (Grid) FindObjectOfType (typeof (Grid));  void OnGUI () grid.color = EditorGUILayout.ColorField (grid.color, GUILayout.Width (200)); 

Okay, jetzt können Sie im Editor überprüfen, ob alles korrekt funktioniert:


Schritt 20: Fügen Sie einen Delegierten hinzu

Jetzt setzen wir einen Delegierten, um die Eingabeereignisse aus der Szenenansicht abzurufen, die wir verwenden = sign, was keine gute Methode ist, da es alle anderen Rückrufe überschreibt. Wir sollten ... benutzen += stattdessen unterschreiben. Lass uns zu unserem gehen GridEditor.cs Skript und diese Änderung vornehmen.

public void OnEnable () grid = (grid) Ziel; SceneView.onSceneGUIDelegate + = GridUpdate; 

Wir müssen auch ein erstellen OnDisable () Rückruf um unsere zu entfernen GridUpdate (), Wenn wir das nicht tun, stapelt es sich und wird mehrfach aufgerufen.

public void OnEnable () grid = (grid) Ziel; SceneView.onSceneGUIDelegate + = GridUpdate;  public void OnDisable () SceneView.onSceneGUIDelegate - = GridUpdate; 

Fazit

Das war's für die Einführung in das Editor-Scripting. Wenn Sie Ihr Know-how erweitern möchten, lesen Sie in der Unity-Skriptreferenz viel über das Thema. Vielleicht möchten Sie das überprüfen Ressourcen, AssetDatabase oder FileUtil Klassen je nach Ihren Bedürfnissen.

Leider sind einige Klassen noch nicht dokumentiert und daher anfällig für Änderungen, ohne zu arbeiten. Zum Beispiel die SceneView Klasse und ihre Funktionen oder Undo.IncrementCurrentEventIndex () Funktion aus der Rückgängig machen Klasse. Wenn die Dokumentation nicht die von Ihnen gesuchten Antworten enthält, möchten Sie vielleicht die Suche in UnityAnswers oder im Unity Forum versuchen.

Vielen Dank für Ihre Zeit!