unity中简单的RedoUndo系统
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UI : MonoBehaviour
{
public Button btn_undo;
public Button btn_redo;
public Button btn_reset;
public Button btn_delete;
public Button btn_rotate;
public Button btn_scaleadd;
public Button btn_scalereduce;
public System.Action UndoClicked;
public System.Action RedoClicked;
public System.Action ResetClicked;
public System.Action RotateClicked;
public System.Action DeleteClicked;
public System.Action<int> ScaleClicked;
private void Awake()
{
btn_scaleadd.onClick.AddListener(() =>
{
ScaleClicked?.Invoke(1);
});
btn_scalereduce.onClick.AddListener(() =>
{
ScaleClicked?.Invoke(-1);
});
btn_delete.onClick.AddListener(() =>
{
DeleteClicked?.Invoke();
});
btn_undo.onClick.AddListener(() =>
{
UndoClicked?.Invoke();
});
btn_redo.onClick.AddListener(() =>
{
RedoClicked?.Invoke();
});
btn_reset.onClick.AddListener(() =>
{
ResetClicked?.Invoke();
});
btn_rotate.onClick.AddListener(() =>
{
RotateClicked?.Invoke();
});
}
}
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Manager : MonoBehaviour
{
private UI gameUI;
private Stack<Command> commandsStack = new Stack<Command>();
private Stack<Command> undoCommandsStack = new Stack<Command>();
public Transform selected;
private void OnEnable()
{
gameUI.UndoClicked += Undo;
gameUI.RedoClicked += Redo;
gameUI.RotateClicked += Rotate;
gameUI.DeleteClicked += Delete;
gameUI.ScaleClicked += Scale;
}
private void OnDisable()
{
gameUI.UndoClicked -= Undo;
gameUI.RedoClicked -= Redo;
gameUI.RotateClicked -= Rotate;
gameUI.DeleteClicked -= Delete;
}
private void Scale(int dir)
{
ScaleCommand s = new ScaleCommand(selected);
s.dir = dir;
s.Do();
commandsStack.Push(s);
}
private void Delete()
{
DeleteCommand delete = new DeleteCommand(selected);
delete.Do();
commandsStack.Push(delete);
selected = null;
}
private void Undo()
{
if (commandsStack.Count > 0)
{
var command = commandsStack.Pop();
command.UnDo();
undoCommandsStack.Push(command);
}
}
private void Redo()
{
if (undoCommandsStack.Count > 0)
{
var command = undoCommandsStack.Pop();
command.Do();
commandsStack.Push(command);
}
}
private void Rotate()
{
RotateCommand rot = new RotateCommand(selected);
rot.Do();
commandsStack.Push(rot);
}
}
public class Command
{
public virtual void Do() { }
public virtual void UnDo() { }
public Transform target;
public Command(Transform t)
{
target = t;
}
}
public class CreateCommand : Command
{
public CreateCommand(Transform t, Vector3 pos, Transform parent) : base(t)
{
this.pos = pos;
this.parent = parent;
}
private Vector3 pos;
private Transform parent;
public Transform newCreated;
public override void Do()
{
base.Do();
newCreated = GameObject.Instantiate(target, pos, Quaternion.identity, parent);
}
public override void UnDo()
{
base.UnDo();
GameObject.Destroy(newCreated.gameObject);
}
}
public class ScaleCommand : Command
{
public ScaleCommand(Transform t) : base(t)
{
}
public int dir;
public override void Do()
{
base.Do();
float s = target.localScale.x;
s += dir * 0.1f;
target.localScale =Vector3.one* s;
}
public override void UnDo()
{
base.UnDo();
float s = target.localScale.x;
s -= dir * 0.1f;
target.localScale = Vector3.one * s;
}
}
public class RotateCommand : Command
{
public RotateCommand(Transform t) : base(t)
{
}
public override void Do()
{
base.Do();
target.transform.Rotate(Vector3.up * 45);
}
public override void UnDo()
{
base.UnDo();
target.transform.Rotate(-Vector3.up * 45);
}
}
public class DeleteCommand : Command
{
public DeleteCommand(Transform t) : base(t)
{
}
public override void Do()
{
base.Do();
target.gameObject.SetActive(false);
}
public override void UnDo()
{
base.UnDo();
target.gameObject.SetActive(true);
}
}