Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How can I create a List<CustomClass> through the Editor in the inspector ?

Discussion in 'Scripting' started by Zbajnek, Dec 3, 2023.

  1. Zbajnek

    Zbajnek

    Joined:
    Nov 29, 2020
    Posts:
    5
    I created a list of custom class I need to use. When I create a property field for this list I cannot edit the elements of the list. What should I change in my code ?

    Here's how it looks like:
    upload_2023-12-3_12-55-26.png

    Here's the code:

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEditor.Rendering;
    5. using UnityEngine;
    6.  
    7. namespace Interaction
    8. {
    9.     public enum InteractableType
    10.     {
    11.         Bed,
    12.         Searchable
    13.     }
    14.  
    15.     [Serializable]
    16.     public class Item
    17.     {
    18.         public ItemData itemData;
    19.         [Range(0f, 100f)] public float chance = 100f;
    20.         [HideInInspector] public float weight;
    21.     }
    22.  
    23.     [Serializable]
    24.     [CreateAssetMenu(fileName = "Interactable", menuName = "Scriptables/Interactable", order = 2)]
    25.     public class InteractionData : ScriptableObject
    26.     {
    27.         public string interactableName;
    28.         public InteractableType interactableType;
    29.  
    30.         [Header("Bed Properties")] [HideInInspector]
    31.         public float warmthBonus;
    32.  
    33.         [Header("Searchable Properties")] [HideInInspector]
    34.         public List<Item> items = new();
    35.     }
    36.  
    37.     [CustomEditor(typeof(InteractionData))]
    38.     public class InteractionDataEditor : Editor
    39.     {
    40.         private SerializedProperty warmthBonus;
    41.         private SerializedProperty items;
    42.  
    43.         private void OnEnable()
    44.         {
    45.             warmthBonus = serializedObject.FindProperty("warmthBonus");
    46.             items = serializedObject.FindProperty("items");
    47.         }
    48.  
    49.         public override void OnInspectorGUI()
    50.         {
    51.             serializedObject.Update();
    52.  
    53.             InteractionData interactionData = (InteractionData)target;
    54.  
    55.             DrawDefaultInspector();
    56.  
    57.             if (interactionData.interactableType == InteractableType.Bed)
    58.             {
    59.                 EditorGUILayout.PropertyField(warmthBonus);
    60.             }
    61.             else if (interactionData.interactableType == InteractableType.Searchable)
    62.             {
    63.                 EditorGUILayout.PropertyField(items);
    64.             }
    65.  
    66.             serializedObject.ApplyModifiedProperties();
    67.         }
    68.     }
    69. }
     
  2. APSchmidt

    APSchmidt

    Joined:
    Oct 31, 2023
    Posts:
    249
    I would not put all the classes in the same script.
    I also don't see how you could possibly add classes to a list.
     
  3. Zbajnek

    Zbajnek

    Joined:
    Nov 29, 2020
    Posts:
    5
    I put the classes together so everyone could see the whole script.

    Of course you can. When I delete [HideInInspector] attribute it works just fine and displays the list with the content of the class, but I don't know how to specifically tell EditorGUI to display the class content.
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,050
    You need a PropertyDrawer that is handling the drawing of Item elements.
     
    Nad_B and Zbajnek like this.
  5. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    594
    You're looking for something like Odin's [InlineEditor]... as @CodeSmile said you need to create a custom editor for this.
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,840
    Well, the issue is this:

    Attributes attached to any serializable collection (arrays or Lists) are not applied to the collection but to each element. It's actually not possible to attach an attribute to an array or list unless you wrap it in a separate class or struct. Since you put a HideInInspector on the array it means the default inspector would not draw the elements but still draws the array.

    Since you create your own inspector, why do you actually use HideInInspector and "DrawDefaultInspector"? Remove than and just draw the properties you want to see.

    Though be careful with such setups. We don't know what your "ItemData" class / struct contains. However if there are serialized references in there it would mean when you switch your "interactableType" to "Bed" all that data would be hidden but still there. So such cases could result in having hidden references to assets which would be inluded in a build and it would be quite hard to debug.