I decided to make a beautiful component. I decided to make a button that adds a new field. A piece of code:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; [CustomEditor(typeof(Starter))] public class StarterEditor : Editor { /// <summary> /// ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ /// </summary> private Starter starter; /// <summary> /// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΏΡ€ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ /// </summary> public void OnEnable() { starter = (Starter)target; } /// <summary> /// ИзмСнСниС Π²ΠΈΠ΄Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° /// </summary> public override void OnInspectorGUI() { int count = starter.managers.Count; EditorGUILayout.IntField("Π Π°Π·ΠΌΠ΅Ρ€", count); //Если ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΠœΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹ Π² памяти, Ρ‚ΠΎ вывСсти ΠΈΡ… список if (starter.managers.Count > 0) { foreach( var manage in starter.managers) { int index = starter.managers.IndexOf(manage); starter.managers[index] = (Manager.ManagerBase)EditorGUILayout.ObjectField("ΠœΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€", manage, typeof(Manager.ManagerBase), false); } } else { /* Если Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² спискС Π½Π΅Ρ‚Ρƒ */ EditorGUILayout.LabelField("НСт Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² спискС"); } //Кнопка добавлСния Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π° if (GUILayout.Button("Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€")) { Manager.ManagerBase newManager = (Manager.ManagerBase)EditorGUILayout.ObjectField("ΠœΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€", null, typeof(Manager.ManagerBase), false); } } } 

But whatever I enter into the if () {} construction is not executed. All connected, and inherited a class from Editor. I will be glad to any help.

  • Show all the code. Inherited from EditorWindow and EditorWindow to OnGUI ? - Suvitruf ♦
  • Added all the code - Dima Marmot
  • And the click on the button works out visually? - Suvitruf ♦
  • Yes, the click works. - Dima Marmot

1 answer 1

The OnInspectorGUI method runs every frame while the inspector window is active. Accordingly, if (GUILayout.Button("Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€")) also checked every frame, and the drawing of the field that is inside the condition occurs only in the frame in which the condition returns true.

As a result, when the button is pressed, the newManager variable is created, into which the result of the field drawing is written. After that, you do nothing with the variable and it is simply deleted when you exit the method, as a result, the button is not pressed in the next frame, you didn’t do anything with the result and the field is not drawn again.

If you had inserted a banal Debug.Log("Π― Ρ‚ΡƒΡ‚ΡŠ"); inside the button click Debug.Log("Π― Ρ‚ΡƒΡ‚ΡŠ"); , then they themselves would have perfectly seen in the console that pressing the button is being worked out, like everything that is written inside the condition.

The output is, for example, a list of your Manager.ManagerBase , in which, by clicking GUILayout.Button("Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€") you will add a new instance of the class. And in the main body of the OnInspectorGUI method OnInspectorGUI you can draw a field through the foreach around the field for each instance that is in this sheet.

Now you draw directly from target, then you can directly add to it, so that you don’t have to rewrite anything.

From your next question, I realized that Manager.ManagerBase is inherited from ScriptableObject , which means that you will not be able to create it using new() and you will have to use something like this to save the new instance to the file system:

 if (GUILayout.Button("Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€")) { Manager.ManagerBaseobj = ScriptableObject.CreateInstance<Manager.ManagerBase>(); AssetDatabase.CreateAsset(obj, "ΠΏΡƒΡ‚ΡŒ Π΄ΠΎ ΠΏΠ°ΠΏΠΊΠΈ"); //здСсь Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ созданный ассСт Π² список Π½Π° отрисовку } 
  • Thanks for the detailed answer. - Dima Marmot