Understanding The Undo Function (JavaScript)

Heyo!

I am trying to use the undo function in Unity, but can’t get it to work. I have been looking at the ScriptReference but there’s a lot of superfluous info making it really difficult for me to understand.

How would I go about performing the most basic Undo?
Where one function registers the entire scene, saving it how it was. Then another function performs the Undo, reverting the scene back to that saved state.

Whenever I try to use Undo.RegisterSceneUndo(), I get the error message:
‘RegisterSceneUndo’ is not a member of ‘Undo’
I am clearly doing something wrong?

Cheers for the help,
Magnus :slight_smile:

The Undo class is an editor class and can only be used inside the Unity editor. Usually there’s a note on the doc page but it seems they forgot it. However if you search the clas in the left class-list you will find the Undo class in the editor-classes-list.

In short you can’t use this class in your game.

UnitySerializer is great, i really applaud whydoidoit for his efforts, but it does introduce some (at least to me) unwanted noise. Another option, something that works out great for me, is to make a clone of the object that you’re performing an action on, storing its transform values, making it a child of a GameObject that you’ve hidden out of the way and then disabling it. You can then undo the action of the object by destroying the current object and replacing it with the clone.

// A custom action class
public class Action {
	var originalObject : GameObject;
	var storedObject : GameObject;
	var storedPosition : Vector3;
	var storedRotation : Vector3;
	var storedScale : Vector3;
	
	function Action ( o : GameObject ) {
		originalObject = o;
		storedObject = MonoBehaviour.Instantiate ( originalObject );
		storedObject.name = storedObject.name.Replace("(Clone)","");
		
		storedPosition = originalObject.transform.position;
		storedRotation = originalObject.transform.localEulerAngles;
		storedScale = originalObject.transform.localScale;		
	}
}

// Needed vars
public var actions : List.< Action > = new List.< Action >();
public var currentAction : Action;
public var undoContainer : Transform;

// Add an action to the actions list
public function AddAction ( obj : GameObject ) {
	var newAction : Action = new Action ( obj );
	
	newAction.storedObject.transform.parent = undoContainer;
	newAction.storedObject.transform.localPosition = Vector3.zero;
	newAction.storedObject.SetActive ( false );
	
	actions.Add ( newAction );

        // Set the maximum amount of undo actions
	if ( actions.Count > 10 ) {
		actions.RemoveAt ( 0 );
	}
	
	currentAction = newAction;
}

// Undo the selected action
public function UndoAction ( action : Action ) {
	action.storedObject.transform.parent = currentLevel.transform;
	action.storedObject.transform.position = action.storedPosition;
	action.storedObject.transform.localEulerAngles = action.storedRotation;
	action.storedObject.transform.localScale = action.storedScale;
	action.storedObject.SetActive ( true );
	
	if ( action.originalObject ) {
		Destroy ( action.originalObject );
	}
	
	actions.Remove ( action );
	
	if ( actions.Count > 0 ) {
		currentAction = actions[actions.Count-1];
	} else {
		currentAction = null;
	}
}

// Undo the current action
public function UndoCurrentAction () {
	if ( currentAction != null ) {
		UndoAction ( currentAction );
	};	
}