Search Unity

[HELP] Arrays not taking arguments in custom inspector

Discussion in 'Scripting' started by Chairman_Meow, Mar 17, 2019.

  1. Chairman_Meow

    Chairman_Meow

    Joined:
    Feb 25, 2016
    Posts:
    13
    So I had the script working and for some reason the script just decided to stop working. I am just trying to make a custom editor which takes a "State" (custom scriptable object) and a string. But when I type in a string the string does not stay in the array in the inspector and when I drag in a "State" the array does not update. Need help!

    Here is my code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Linq;
    4.  
    5. [CreateAssetMenu(menuName = "State")]
    6.  
    7. [Serializable]
    8. public class State : ScriptableObject
    9. {
    10.     [TextArea(20, 20)] [SerializeField] private string storyText;
    11.     [SerializeField] public bool multiplePaths;
    12.     [SerializeField] public int numberOfPaths = 1;
    13.     [SerializeField] public State[] nextState;
    14.     [SerializeField] public string[] letterForNextState;
    15.  
    16.     public string GetStateStory()
    17.     {
    18.         return storyText;
    19.     }
    20.  
    21.     public State GetNextStates(int n)
    22.     {
    23.         return nextState[n];
    24.     }
    25. }
    26.  
    My Custom Editor Script:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(State))]
    5. public class StateEditor : Editor
    6. {
    7.     public SerializedProperty commands;
    8.  
    9.     public override void OnInspectorGUI()
    10.     {
    11.         State state = (State)target;
    12.         state.numberOfPaths = EditorGUILayout.IntField("Number of Paths", state.numberOfPaths);
    13.         state.nextState = new State[state.numberOfPaths];
    14.  
    15.         if (state.numberOfPaths == 1)
    16.         {
    17.             GUILayout.BeginHorizontal();
    18.             GUILayout.Label("State" + 1);
    19.             state.nextState[0] = (State)EditorGUILayout.ObjectField(state.nextState[0], typeof(State), true);
    20.             GUILayout.Label("[ENTER]");
    21.             GUILayout.EndHorizontal();
    22.         }
    23.         else if (state.numberOfPaths > 1)
    24.         {
    25.             state.letterForNextState = new string[state.numberOfPaths];
    26.             for (int i = 0; i < state.numberOfPaths; i++)
    27.             {
    28.                 GUILayout.BeginHorizontal();
    29.                 GUILayout.Label("State" + i);
    30.                 state.nextState[i] = (State)EditorGUILayout.ObjectField(state.nextState[i], typeof(State), true);
    31.                 GUILayout.Label("Option");
    32.                 state.letterForNextState[i] = EditorGUILayout.TextField(state.letterForNextState[i]);
    33.                 GUILayout.EndHorizontal();
    34.             }
    35.         }
    36.     }
    37. }
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    You are creating new states each time oninspectorGUI is called and replacing whatever was stored there.
     
  3. Chairman_Meow

    Chairman_Meow

    Joined:
    Feb 25, 2016
    Posts:
    13
    OK... How can I fix that? Sorry, Im a terrible programmer
     
  4. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Well, delete your editor script. It is doing more harm than good tbh. When editing a scriptable object in an editor script you need to load and save the asset. You can set the number of possible paths in the editor simply by the number of states you put into your array.

    Try using this for your State script instead and then just add possible paths by adding states to the nextState array in the inspector.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(menuName = "State")]
    4. public class State : ScriptableObject
    5. {
    6.     [TextArea(20, 20), SerializeField]
    7.     private string storyText;
    8.  
    9.     public bool multiplePaths { get { return nextState.Length > 1; } }
    10.  
    11.     public int numberOfPaths { get { return nextState.Length; } }
    12.  
    13.     public State[] nextState;
    14.  
    15.     public string[] letterForNextState;
    16.  
    17.     public string GetStateStory()
    18.     {
    19.         return storyText;
    20.     }
    21.  
    22.     public State GetNextStates(int n)
    23.     {
    24.         return nextState[n];
    25.     }
    26. }
     
    Chairman_Meow likes this.
  5. Chairman_Meow

    Chairman_Meow

    Joined:
    Feb 25, 2016
    Posts:
    13
    Thanks! However, I was trying to avoid having so many fields visible... I wanted the letterForNextState to appear only if the numberOfPaths was greater than 1, and then have nextState horizontally align with its corresponding letterForNextState.