Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved How to serialize specific fields that are inside an array of classes?

Discussion in 'Scripting' started by IlnurNu, Jul 14, 2023.

  1. IlnurNu

    IlnurNu

    Joined:
    May 26, 2018
    Posts:
    2
    If I have a script like that

    Code (CSharp):
    1. public enum VariableToShow { First, Second, Third };
    2.  
    3.     public class TestSerialization : MonoBehaviour
    4.     {
    5.         public B[] ExampleField;
    6.     }
    7.  
    8.     [Serializable]
    9.     public class A
    10.     {
    11.         public B[] BInstances;
    12.     }
    13.  
    14.     [Serializable]
    15.     public class B
    16.     {
    17.         public VariableToShow ShowVariable;
    18.  
    19.         public int FirstVariable;
    20.         public int SecondVariable;
    21.         public int ThirdVariable;
    22.     }
    And I need to only show the field in class B that is being selected by ShowVariable (if ShowVariable == First, then show FirstVariable, ShowVariable == Second, then show SecondVariable, etc), how can I do that?
    I know that I can use SerializedProperty and serializedObject in custom editor, but I can only do it if instead of an array of B there are just variables inside the MonoBehaviour, I would do it like that

    Code (CSharp):
    1. public enum VariableToShow { First, Second, Third };
    2.  
    3.     public class TestSerialization : MonoBehaviour
    4.     {
    5.         public VariableToShow ShowVariable;
    6.  
    7.         public int FirstVariable;
    8.         public int SecondVariable;
    9.         public int ThirdVariable;
    10.     }
    And inside editor for that script:
    Code (CSharp):
    1. public override void OnInspectorGUI()
    2.         {
    3.             serializedObject.Update();
    4.  
    5.             SerializedProperty iterator = serializedObject.GetIterator();
    6.  
    7.             List<string> includes = new List<string>() { "ShowVariable" };
    8.             bool enterChildren = true;
    9.             while (iterator.NextVisible(enterChildren))
    10.             {
    11.                 enterChildren = false;
    12.  
    13.                 if (!includes.Contains(iterator.propertyPath))
    14.                     continue;
    15.  
    16.                 if (iterator.propertyPath == "ShowVariable")
    17.                 {
    18.                     VariableToShow showVariable = iterator.GetEnumValue<VariableToShow>();
    19.  
    20.                     switch (showVariable)
    21.                     {
    22.                         case VariableToShow.First:
    23.                             includes.Add("FirstVariable");
    24.                             break;
    25.                         case VariableToShow.Second:
    26.                             includes.Add("SecondVariable");
    27.                             break;
    28.                         case VariableToShow.Third:
    29.                             includes.Add("ThirdVariable");
    30.                             break;
    31.                     }
    32.                 }
    33.  
    34.                 EditorGUILayout.PropertyField(iterator, true);
    35.             }
    36.  
    37.             serializedObject.ApplyModifiedProperties();
    38.         }

    Can I do something similar for nested fields in array of classes? I tried to use iterator.NextVisible and putting true in there, but it just printed them out weird even when I used EditorGUILayout.FoldOut and EditorGUI.indentLevel. Would really be glad if someone helped me with this!

    Don't mind the public fields, only using it rn to show an example
     
  2. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    You can create a custom PropertyDrawer for class B, instead of a custom editor for the classes that contain instances of B. Then, everywhere that you have an instance of B serialized, including in an array of B's, it will display how you script it to display.
     
    IlnurNu likes this.
  3. IlnurNu

    IlnurNu

    Joined:
    May 26, 2018
    Posts:
    2
    Yes, that did exactly what I wanted, thanks a lot!
     
    CodeRonnie likes this.