Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] How to make undo work over multiple frames (Custom Editor)

Discussion in 'Editor & General Support' started by MCrafterzz, Jun 9, 2018.

  1. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Hello, I'm trying to get the undo to work when moving a object. I have tried using the Undo.RecordObject method together with EditorUtitility.MarkDirty but it didn't work.

    Code:
    Code (CSharp):
    1. if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && objectToMove == null)
    2.         {
    3.                 objectToMove = raycastHit.collider.gameObject;
    4.                 objectToMove.GetComponent<BoxCollider>().enabled = false;
    5.                 Undo.RecordObject (objectToMove, "Move Object");
    6.         }
    7.         else if (guiEvent.type == EventType.MouseDrag && objectToMove != null)
    8.         {
    9.             objectToMove.transform.position = hitPosition;
    10.         }
    11.         else if (guiEvent.type == EventType.MouseUp && guiEvent.button == 0 && objectToMove != null)
    12.         {
    13.             objectToMove.GetComponent<BoxCollider>().enabled = true;
    14.             EditorUtility.SetDirty(objectToMove);
    15.             objectToMove = null;
    16.         }
    What I want is when pressing CTRL-Z it should revert back to the position before moving the object. I think the problem is that I happens across multiple frames which I haven't seen anyone else do. How can this be solved?
     
  2. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
  3. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
  4. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Thx. I am using:
    Undo.SetCurrentGroupName("Move point");
    and Undo.CollapseUndoOperations(Undo.GetCurrentGroup());

    It does seem to create a undo but CTRL-Z doesn't change the position

    Full code:
    Code (CSharp):
    1. if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && objectToMove == null)
    2.         {
    3.                 objectToMove = raycastHit.collider.gameObject;
    4.                 objectToMove.GetComponent<BoxCollider>().enabled = false;
    5.                 Undo.SetCurrentGroupName("Move point");
    6.         }
    7.         else if (guiEvent.type == EventType.MouseDrag && objectToMove != null)
    8.         {
    9.             objectToMove.transform.position = hitPosition;
    10.         }
    11.         else if (guiEvent.type == EventType.MouseUp && guiEvent.button == 0 && objectToMove != null)
    12.         {
    13.             objectToMove.GetComponent<BoxCollider>().enabled = true;
    14.             Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
    15.             objectToMove = null;
    16.         }
     
    Last edited: Jun 10, 2018
  5. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    Sorry, editing my previous reply.

    I think you still need to add in Undo.RecordObject
    Code (CSharp):
    1. if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && objectToMove == null)
    2.         {
    3.                 objectToMove = raycastHit.collider.gameObject;
    4.                 objectToMove.GetComponent<BoxCollider>().enabled = false;
    5.                 Undo.SetCurrentGroupName("Move point");
    6.         }
    7.         else if (guiEvent.type == EventType.MouseDrag && objectToMove != null)
    8.         {
    9.             Undo.RecordObject(objectToMove, "Moved Object")
    10.             objectToMove.transform.position = hitPosition;
    11.         }
    12.         else if (guiEvent.type == EventType.MouseUp && guiEvent.button == 0 && objectToMove != null)
    13.         {
    14.             objectToMove.GetComponent<BoxCollider>().enabled = true;
    15.             Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
    16.             objectToMove = null;
    17.         }
     
    MCrafterzz likes this.
  6. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Still doesn't work. CTRL-Z does nothing :C
     
  7. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    By default, unity will only flush undo operations after certain events, such as key presses or mouse up. Additionally, undo operations are automatically combined by type -- so your repeated position changes should automatically be combined by unity, and flushed on mouse up.

    Oh, also you want to record the transform, not the gameobject. The transform is what changed.

    This should work just fine:

    Code (CSharp):
    1. if ( guiEvent.type == EventType.MouseDown && guiEvent.button == 0 ) {
    2.         objectToMove = raycastHit.collider.gameObject;
    3.         objectToMove.GetComponent<BoxCollider>().enabled = false;
    4. }
    5.  
    6. if( objectToMove != null ) {
    7.     if ( guiEvent.type == EventType.MouseDrag ) {
    8.         Undo.RecordObject( objectToMove.transform, "Moved Object" );
    9.         objectToMove.transform.position = hitPosition;
    10.     } else if ( guiEvent.type == EventType.MouseUp && guiEvent.button == 0 ) {
    11.         objectToMove.GetComponent<BoxCollider>().enabled = true;
    12.         objectToMove = null;
    13.     }
    14. }
    Note: Collapsing the undo groups as you were doing them was doing nothing because you're always getting the current group, meaning you're effectively collapsing nothing. If you wanted to collapse the groups properly, you'd need to save the undo group when you first start the operation. Dealing with undo groups is totally unnecessary for this application, though.
     
    Last edited: Jun 11, 2018
    Bezoro and flashframe like this.
  8. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    I created a new project with a cube and a simple script and it still didn't work. The test project is in 2018.1 and the normal one is in 2018.2b6
     
  9. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Then you're doing something wrong. This kind of setup is exactly what I use in my own editor scripts.
     
  10. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    I'm curently uploading it to github
     
  11. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
  12. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    You're still not recording the transform.
     
  13. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354

    Facepalm :/ Thx.