Search Unity

Getting an Editor to work in a struct from a scriptable object?

Discussion in 'Scripting' started by Darkness-Seeker, Nov 3, 2019.

  1. Darkness-Seeker

    Darkness-Seeker

    Joined:
    Jun 18, 2016
    Posts:
    11
    The idea I had behind this is "quite" simple, but I can't get it to work somehow: When I create a new Scrptable Object of the type "Quest", it would have an array of structs setting the ammount of "objectives" said quest would have. The problem is I've been trying to create an editor to update which variables show up in the struct depending of what objetive type is selected for that objective (if it's interactive, the actual target, if it's to kill what are you supposed to kill and how many, etc) but it doesn't update:

    Quest.Cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [System.Serializable]
    6. public struct QuestObjective
    7. {
    8.     public enum ObjectiveType {Interact,Kill,Gather}
    9.     public ObjectiveType objectiveType;
    10.     public string objectiveResume;
    11.  
    12.     public GameObject interactTarget;
    13.  
    14.     public string killTarget;
    15.     public int ammountKillTarget;
    16.  
    17.     public string gatherTarget;
    18.     public int ammountGatherTarget;
    19. }
    20.  
    21. [CreateAssetMenu(fileName = "Quest",menuName = "New Quest")]
    22. public class Quest : ScriptableObject
    23. {
    24.     public string questName;
    25.     public GameObject questGiver;
    26.     public GameObject questEnder;
    27.     public QuestObjective[] objectives;
    28. }
    QuestStructEditor.Cs
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(QuestObjective)), CanEditMultipleObjects]
    5. public class QuestStructEditor : Editor
    6. {
    7.     public SerializedProperty
    8.         objective_type,
    9.         interact_target,
    10.         kill_target,
    11.         ammountKill_target,
    12.         gather_target,
    13.         ammountGather_target;
    14.  
    15.     private void OnEnable()
    16.     {
    17.         //Setup the Serialized Properties
    18.         objective_type = serializedObject.FindProperty("objectiveType");
    19.         interact_target = serializedObject.FindProperty("interactTarget");
    20.         kill_target = serializedObject.FindProperty("killTarget");
    21.         ammountKill_target = serializedObject.FindProperty("ammountKillTarget");
    22.         gather_target = serializedObject.FindProperty("gatherTarget");
    23.         ammountGather_target = serializedObject.FindProperty("ammountGatherTarget");
    24.     }
    25.  
    26.     public override void OnInspectorGUI()
    27.     {
    28.         serializedObject.Update();
    29.  
    30.         EditorGUILayout.PropertyField(objective_type);
    31.  
    32.         QuestObjective.ObjectiveType ot = (QuestObjective.ObjectiveType)objective_type.enumValueIndex;
    33.        
    34.         switch (ot)
    35.         {
    36.             case QuestObjective.ObjectiveType.Gather:
    37.                 EditorGUILayout.PropertyField(gather_target, new GUIContent("gatherTarget"));
    38.                 EditorGUILayout.IntSlider(ammountGather_target, 0, 500, new GUIContent("ammountGatherTarget"));
    39.                 break;
    40.  
    41.             case QuestObjective.ObjectiveType.Interact:
    42.                 EditorGUILayout.PropertyField(interact_target, new GUIContent("interactTarget"));
    43.                 break;
    44.  
    45.             case QuestObjective.ObjectiveType.Kill:
    46.                 EditorGUILayout.PropertyField(kill_target, new GUIContent("killTarget"));
    47.                 EditorGUILayout.IntSlider(ammountKill_target, 0, 500, new GUIContent("ammountKillTarget"));
    48.                 break;
    49.         }
    50.  
    51.         serializedObject.ApplyModifiedProperties();
    52.     }
    53. }
    54.  
    I'm working in Unity 2019.2.5f, and I've tried setting the editor inside the Editor folder, just along other scripts as I have in other projects where I have used the editor, but it seems is something related to the code.
    Any idea what could be wrong?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    I don't think you can custom-edit a non-ScriptableObject or non-Monobehavior thingy. Your code above says it's an QuestObjective editor... I think you need to make it a Quest editor to use a custom editor/inspector.
     
    Bunny83 likes this.
  3. Darkness-Seeker

    Darkness-Seeker

    Joined:
    Jun 18, 2016
    Posts:
    11
    Oh, didn't know that the structs were not supported. I just tried to remove all the struct part from the code and turn it into it's own serializable class to call it from the "quest" serializable object, but it seems it still doesn't work.

    QuestObjective.Cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [System.Serializable]
    6. public class QuestObjective
    7. {
    8.     public enum ObjectiveType { Interact, Kill, Gather }
    9.     public ObjectiveType objectiveType;
    10.     public string objectiveResume;
    11.  
    12.     public GameObject interactTarget;
    13.  
    14.     public string killTarget;
    15.     public int ammountKillTarget;
    16.  
    17.     public string gatherTarget;
    18.     public int ammountGatherTarget;
    19.    
    20. }
    Any ideas?
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    For things you can select, that are their own things (MonoBehaviours, ScriptableObjects), you create custom Editors. For things that are part of other things - Serializable classes or structs - you create custom Property Drawers.
     
    Kurt-Dekker likes this.
  5. vycanis1801

    vycanis1801

    Joined:
    Feb 11, 2020
    Posts:
    12
    I know this is a few years old but In case OP never figured this out or a rando comes across this post. To help with the question at hand, it might be better to subclass your QuestObjective struct. Ofc, first you need to make it a class bc structs cannot be subclassed.
     
  6. FreshDeveloper

    FreshDeveloper

    Joined:
    Jun 2, 2019
    Posts:
    2
    structs are currently supported!!!!! just write [serializable] and keep going