Unity撤销功能采用命令模式,本代码可以进行多组模型以此撤销,如果有人觉得一一拖拽麻烦可以自己更改通过便利根节点代码加入。
状态管理类
using System;
using System.Collections.Generic;
using UnityEngine;
public class MStateManager : MonoBehaviour
{
// 用于记录需要管理的物体
public List<GameObject> objectsToManage = new List<GameObject>();
private void Awake()
{
// 记录所有需要管理的物体的初始状态
foreach (GameObject obj in objectsToManage)
{
obj.AddComponent<Memento>();
obj.GetComponent<Memento>().SaveState();
}
}
public void StateSave()
{
// 记录所有需要管理的物体的初始状态
foreach (GameObject obj in objectsToManage)
{
obj.AddComponent<Memento>();
obj.GetComponent<Memento>().SaveState();
}
}
// 撤销操作
public void Undo()
{
foreach (GameObject obj in objectsToManage)
{
Memento memento = obj.GetComponent<Memento>();
if (memento != null)
{
memento.Undo();
}
}
}
// 重做操作
public void Redo()
{
foreach (GameObject obj in objectsToManage)
{
Memento memento = obj.GetComponent<Memento>();
if (memento != null)
{
memento.Redo();
}
}
}
private class Memento : MonoBehaviour
{
private Stack<State> undoStack = new Stack<State>();
private Stack<State> redoStack = new Stack<State>();
private class State
{
public Vector3 position;
public Vector3 scale;
public bool isHidden;
public Color color;
public State(Vector3 position, Vector3 scale, bool isHidden, Color color)
{
this.position = position;
this.scale = scale;
this.isHidden = isHidden;
this.color = color;
}
}
public void SaveState()
{
undoStack.Push(new State(transform.position, transform.localScale, !gameObject.activeSelf, GetComponent<Renderer>().material.color));
}
public void Undo()
{
if (undoStack.Count >0)
{
State state = undoStack.Pop();
redoStack.Push(new State(transform.position, transform.localScale, !gameObject.activeSelf, GetComponent<Renderer>().material.color));
transform.position = state.position;
transform.localScale = state.scale;
gameObject.SetActive(!state.isHidden);
GetComponent<Renderer>().material.color = state.color;
}
}
public void Redo()
{
if (redoStack.Count > 0)
{
State state = redoStack.Pop();
undoStack.Push(new State(transform.position, transform.localScale, !gameObject.activeSelf, GetComponent<Renderer>().material.color));
transform.position = state.position;
transform.localScale = state.scale;
gameObject.SetActive(!state.isHidden);
GetComponent<Renderer>().material.color = state.color;
}
}
}
}
测试类
using UnityEngine;
public class Example : MonoBehaviour
{
public GameObject Cube1;
public GameObject Cube2;
private MStateManager stateManager;
private void Start()
{
stateManager =GetComponent<MStateManager>();
stateManager.objectsToManage.Add(Cube1);
stateManager.objectsToManage.Add(Cube2);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
stateManager.Undo();
}
else if (Input.GetKeyDown(KeyCode.Y))
{
stateManager.Redo();
}
if (Input.GetKeyDown(KeyCode.P))
{
Cube1.transform.position += Vector3.right;
stateManager.StateSave();
}
if (Input.GetKeyDown(KeyCode.W))
{
Cube2.transform.position += Vector3.right;
stateManager.StateSave();
}
}
}