Search Unity

UndoRedo not restoring values on item inside List

Discussion in 'Immediate Mode GUI (IMGUI)' started by CDF, Jun 26, 2015.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    Hi, I'm experiencing some weirdness with UndoRedo where upong performing a redo, values are not restored on items inside a list, here's some simple code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.Collections;
    4.  
    5. [CreateAssetMenu]
    6. public class TestList : ScriptableObject {
    7.  
    8.     public List<TestChild> children = new List<TestChild>();
    9. }
    10.  
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [System.Serializable]
    5. public class TestChild {
    6.  
    7.     public float testValue = 1;
    8. }
    9.  
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [CustomEditor(typeof(TestList))]
    6. public class TestListEditor : Editor {
    7.  
    8.     public override void OnInspectorGUI() {
    9.        
    10.         base.OnInspectorGUI();
    11.  
    12.         if (GUILayout.Button("Add")) {
    13.  
    14.             //get the list
    15.  
    16.             TestList list = target as TestList;
    17.  
    18.             //record the list before making changed
    19.  
    20.             Undo.RecordObject(list, "Create Child");
    21.  
    22.             //create the child and add to list, it has a default "testValue" as 1
    23.            
    24.             TestChild child = new TestChild();
    25.             list.children.Add(child);
    26.  
    27.             //make the list dirty
    28.  
    29.             EditorUtility.SetDirty(list);
    30.         }
    31.     }
    32. }
    33.  
    When pressing the "Add" button, the script creates a TestChild which has a default value of 1 and adds it to list. Upon performing an UndoRedo, testValue = 0

    Is this a bug or am I missing something? I'm using unity 5.1.1

    Thanks
     
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    Just confirmed this is not an issue in Unity 4.5.5
     
  3. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
    Last edited: Jun 28, 2015
  4. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    TestChild is not a game object, it's a simple serializable class
     
  5. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
    QUOTE="CDF, post: 2183312, member: 407135"]TestChild is not a game object, it's a simple serializable
    class[/QUOTE]

    Oh you are right. Missed that.

    Try using Undo.RegisterCompleteObjectUndo() instead then
     
  6. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    Ah that works, strange it isn't documented...
     
  7. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    Ok, now with serializedProperties, same issue as before, here's an updated Add method:

    Code (CSharp):
    1. if (GUILayout.Button("Add")) {
    2.  
    3.     serializedObject.Update();
    4.     serializedObject.FindProperty("children").arraySize++;
    5.     serializedObject.FindProperty("children").GetArrayElementAtIndex(0).FindPropertyRelative("testValue").floatValue = 1;
    6.     serializedObject.ApplyModifiedProperties();
    7. }
    When redoing, testValue is 0 again.
     
  8. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    This is very strange.



    strings are added in this orider: "hello 4", "hello 6", "hello 9", inserted at element 0.
    You can see in the image, that the items in the list below the last are restored correctly on Redo. And for some reason when a child is removed (other than the last), the last is restored.

    This is just using serializedObjects and properties as posted above. Anyone have any idea why this is happening?