R
RobotoSkunk
Guest
Hi, I'm creating an editor for my video game and I want to add the option to be able to undo and redo actions, but I have no idea how to do it. Can someone help me?
Thanks for everything you said to me, it helps me quite seriously <3I recommend reading about the Command Pattern:
http://gameprogrammingpatterns.com/command.html
These is a section specifically on undo/redo.
It gives a good overview of a way to approach the whole thing.
Basically, for every action the user makes, you need to save the exact information required to undo do it.
As @FlameRooster suggested, you'll want some sort of data structure and/or object system that you can save that information to.
So if the user moves an object from location A to location B, you would record the information:
1) Object Moved. ( An enum could be used to store the different types of actions the user can perform )
2) Original x and y location.
And save it to an array / data structure / unique instance.
Then when the user hits undo, you can perform the appropriate action of moving the object back to location A, then remove the undo information from the undo data structure.
And once saved in the list what should I do with the ID or how is that the code to do the Undo/Redo button?Just before deactivating the instances, save all the instance ids to a data structure ( I use a ds_list ).
I have a top level object that all other objects use as a parent.
with (obj_parent)
{
if object is outside camera view
add instance id to ds_list
deactivate instance
}
And do the reverse to reactivate them.
Or you can just use the function instance_activate_all() followed by instance_deactivate region()
// Grab the last instance that was added to the undo list
var _instance = global.undo_list[| ds_list_size(global.undo_list) - 1];
// Grab the undo information here - need to add code for this depending on how you implement it.
// [ Grab instance undo info here]
Code goes here...
// Perform the undo action
_instance.x = prev_x;
_instance.y = prev_y;
// Delete the instance from the undo list, because we've undone that action.
ds_list_delete(global.undo_list, ds_list_size(global.undo_list) - 1);
// Also clean up other undo information
undo_instance = noone;
undo_prev_x = 0;
undo_prev_y = 0;
undo_instance.x = undo_prev_x;
undo_instance.y = undo_prev_y;
var _object_undo = instance_create_layer(x, y, "Instances", obj_undo_move);
// NOTE : In the editor, you will need to detect when the user starts dragging the object in order to move it, save its original x and y position somewhere, and then, when they finish dragging and complete the move operation, use those values in the following code. Also need to record the moved instances id.
// Assume your main editor object controller is called obj_editor:
_object_undo.undo_instance = obj_editor.moved_object_id;
_object_undo.undo_prev_x = obj_editor.moved_object_original_x;
_object_undo.undo_prev_y = obj_editor.moved_object_original_y;
// Add the new undo instance to the end of a datastructure, i.e. a ds_list
ds_list_add(global.undo_list, _object_undo);
// Grab the most recent undo operation the user recorded.
var _undo_obj = global.undo_list[| ds_list_size(global.undo_list) - 1];
// Perform the undo operation by running the User Event 0 on the object.
with ( _undo_obj )
{
event_user(0)
}
// Delete the undo object from the list.
ds_list_delete(global.undo_list, ds_list_size(global.undo_list) - 1);
// Destroy the undo object
instance_destroy(_undo_obj);