📜 ⬆️ ⬇️

UnityEditor, dynamic content editor component

While working on my game in Unity, I wondered why I should create many similar scripts describing the behavior of game objects, but having small differences from each other, if I could create one, and adding it as a component to an object would simply choose the type of the object itself, in the editor (also known as the Inspector), I would see only those properties and fields that are directly related to the selected type. It would also allow to use certain methods depending on the choice inside the script. This was helped by the UnityEditor namespace and its Editor class.


Update 1
Received comments on the publication prompted caution. Despite the attractiveness of the described method for solving various problems, one should not abuse it, but use it carefully and rationally. Do not make your code from object-oriented turned into a mess.

The first thing I encountered was how to implement a drop-down list in the editor. Finding the first topics on the forums on the Internet, it seemed that it was not so easy, but patience led me to use the usual listing:
')
using UnityEngine; public class TestComponent : MonoBehaviour { //     . //    ,     . public enum ComponentType {First = 1, Second = 2}; public ComponentType component; } 


Result

Further. For example, we need our component to store a field of type string containing text. And also we should have two integer variables: the first has a value associated with the first option, the second, respectively, with the second.

The resulting TestComponent.cs file:

 using UnityEngine; public class TestComponent : MonoBehaviour { public enum ComponentType {First = 1, Second = 2}; public ComponentType component; public string componentName; public int variableComponentFirst; public int variableComponentSecond; } 


It turned out this way, but this is not what we need.

Now we want that when choosing the first option in the editor we see the field for editing only the first variable, the second is hidden. If the second option is chosen - vice versa. These variables can have values ​​from 0 to 100 and in the editor are presented in the form of a slider (slider). A text field is also dependent on the option selected.

To implement all this, I used the UnityEditor namespace and inheritance from the Editor class, which in this case allows us to redraw the editor window as we want from the code. Code written to change the component editor should not be written in the same script where the functionality of the described component is described, since this code is used only at the development stage, and it should not be in the finished project. To do this, in the Assets folder, you need to create a special Editor folder and store all scripts in it to change the editor's view of one or another component. The scripts contained in this folder will not interfere with the list of available scripts when adding them through the Inspector .

The corresponding TestComponentEditor.cs script with comments:

 //      using UnityEditor; using UnityEngine; //        [CustomEditor( typeof(TestComponent) )] [CanEditMultipleObjects] public class TestComponentEditor : Editor { TestComponent subject; SerializedProperty compType; SerializedProperty compName; SerializedProperty varCompFirst; SerializedProperty varCompSecond; //         void OnEnable () { subject = target as TestComponent; compType = serializedObject.FindProperty("component"); compName = serializedObject.FindProperty ("componentName"); varCompFirst = serializedObject.FindProperty ("variableComponentFirst"); varCompSecond = serializedObject.FindProperty ("variableComponentSecond"); } //    public override void OnInspectorGUI() { //   .        //      . serializedObject.Update (); //     EditorGUILayout.PropertyField(compType); //     EditorGUILayout.PropertyField(compName); //    compName.stringValue = "None"; //     , if(subject.component == TestComponent.ComponentType.First) { //    EditorGUILayout.IntSlider (varCompFirst, 0, 100, new GUIContent ("Variable First")); compName.stringValue = "First"; } else if(subject.component == TestComponent.ComponentType.Second) { EditorGUILayout.IntSlider (varCompSecond, 0, 100, new GUIContent ("Variable Second")); compName.stringValue = "Second"; } //    serializedObject.ApplyModifiedProperties (); } } 


The first option is selected.


Selected second option

By the way, it is not necessary to erase the standard editor, and then completely redraw it. If you want to make minor changes in the standard component editor, you can use the DrawDefaultInspector () method in order not to redraw the component editor, but to supplement it. We write the method at the very beginning of the rendering event of the OnInspectorGUI () editor. Note that the editor fields created in the TestComponentEditor script do not replace the public fields of the TestComponent script in the editor, but are added below. In this case, both will work with the same variable. To leave the new version of the field in the editor, in the TestComponent script, add the attribute [HideInInspector] in front of the corresponding public variable.

Further it would be possible to go deep. Try other types of variables and ways to edit them. Sort of curves for editing and progress bars for displaying values. The EditorGUILayot class and the neighbor classes provide us with such features. It would also be possible to work with some methods, when, depending on the choice, some do not work. But all this and much more will leave you to implement your own ideas, limited by your own imagination. I just showed you what you could do.

Editor class in Unity documentation.

Source: https://habr.com/ru/post/269541/


All Articles