Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete this survey (open until May 15, 2024).
    Dismiss Notice

Inspector - SerializedObject - ScriptableObject - Undo

Discussion in 'Immediate Mode GUI (IMGUI)' started by phawthor, Dec 12, 2014.

  1. phawthor

    phawthor

    Joined:
    Dec 12, 2014
    Posts:
    3
    Hi,

    I have been working on a custom Inspector script lately and all worked well so far. I now want to add Undo functionality for the Inspector properties. I understand I have to use SerializedObject and SerializedProperty for this. All fine when dealing with properties of the monobehaviour script itself.

    But I want to use this as well on the properties of a class with an instance of this class in the monobehaviour script. If I am right I have to set up the class as a ScriptableObject. Again all seems to work well in the simple example below. After creating the instance, the “calculate” button in the Inspector returns the correct value directly from the instance as expected.

    But here is the problem, as soon as I reload the scene it seems I have no longer access to the properties in the created instance unless I access them through SerializedObject > SerializedProperty which in my case is not always what I want, check for example the Calculate button which should return the data directly from the instance.

    Then I change the script with, for the below code, unrelevant changes, save it, and all is working correctly afterwards. I read in the docs that on scripts changes the unity assemblies are reloaded which also involves dealing with the serialized objects etc. So somehow the “calculate” button code works correctly again after Unity reloads the assemblies. But I cannot see what I am doing wrong, shouldn’t all this just work fine as well on reloading the scene?

    Anyone knows what is going wrong here?

    Thanks!

    Peter

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. [System.Serializable]
    7. public class SerClass : ScriptableObject
    8. {
    9.   [SerializeField]
    10.   public int intV = 10;
    11.   [SerializeField]
    12.   public int intW = 10;
    13.  
    14.   public int Calculate(){
    15.        return intV * intW;
    16.   }
    17. }
    18.  
    19. public class serializedTest : MonoBehaviour {
    20.  
    21.   public int intTest = 10;
    22.   public SerClass sInstance;
    23.  
    24.   // Use this for initialization
    25.   void Start () {
    26.   }
    27.  
    28.   // Update is called once per frame
    29.   void Update () {
    30.   }
    31.  
    32. }
    33.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. [CustomEditor (typeof(serializedTest))]
    7. public class serializedTestEDitor : Editor  {
    8.  
    9. // monobehaviour serialized object
    10.   public  SerializedObject m_SerObj;
    11.  
    12.   // SerClass serialized object
    13.   public  SerializedObject m_SerObj2;
    14.  
    15.  
    16. // monobehaviour serialized property
    17.   SerializedProperty m_int;
    18.  
    19.   // SerClass serialized properties
    20.   SerializedProperty m_intV;
    21.   SerializedProperty m_intW;
    22.  
    23.   public serializedTest scr;
    24.  
    25.   public void OnEnable()
    26.   {
    27.     scr = (serializedTest)target;
    28.  
    29.     m_SerObj = new SerializedObject (target);
    30.     m_int = m_SerObj.FindProperty("intTest");
    31.   }
    32.  
    33.  
    34.   public override void OnInspectorGUI()
    35.   {
    36.     m_SerObj.Update();
    37.  
    38.     if(scr. sInstance != null) m_SerObj2.Update();
    39.  
    40.     m_int.intValue = EditorGUILayout.IntField("SideObject Name", m_int.intValue);
    41.  
    42.     if(GUILayout.Button ("Create Instance")){
    43.         scr.sInstance = ScriptableObject.CreateInstance(typeof(SerClass)) as SerClass;
    44.         m_SerObj2 = new SerializedObject (scr.sInstance);
    45.         m_intV = m_SerObj2.FindProperty("intV");
    46.         m_intW = m_SerObj2.FindProperty("intW");
    47.     }
    48.  
    49.     If(m_SerObj2 != null){
    50.         m_intV.intValue = EditorGUILayout.IntField("  Int value", m_intV.intValue);
    51.         m_intW.intValue = EditorGUILayout.IntField("  Int value", m_intW.intValue);
    52.     }
    53.  
    54.     m_SerObj.ApplyModifiedProperties();
    55.  
    56.     If(m_SerObj2 != null)m_SerObjcts2.ApplyModifiedProperties();
    57.  
    58.     if(GUILayout.Button ("Calculate")){
    59.        Debug.Log(scr.sInstance.Calculate());
    60.     }
    61.   }
    62. }
    63.  
     
    Last edited: Dec 12, 2014