Unity 备忘录模式
初学者,自用笔记
用于在不破坏封装的前提下,捕获并保存对象某一时刻的内部状态(快照),以便之后恢复到该状态。它常用于:撤销/回滚、复活点、编辑器历史、回放校正等
复活点用于死亡复活时,通过备忘录模式回滚到最近的检查点;而存档系统则用于将游戏数据持久化保存,并在下次进入游戏时读取并恢复进度。
- Originator(发起者):需要被保存/恢复状态的对象;负责创建备忘录与从备忘录恢复。
- Memento(备忘录/快照):状态快照对象;对外应尽量不可变/只读,避免被随意篡改。
- Caretaker(管理者):负责保存/管理备忘录(历史栈、列表、存档槽),但不应直接修改备忘录内容。
简单例子
Originator
// 发起者(负责创建快照、从快照恢复)
public sealed class RestorableTransform : MonoBehaviour
{
// 创建快照(捕获当前状态)
public TransformMemento CreateMemento()
{
return new TransformMemento(transform.position, transform.rotation);
}
// 从快照恢复
public void Restore(TransformMemento memento)
{
transform.position = memento.Position;
transform.rotation = memento.Rotation;
}
}
Memento
// 备忘录(快照)
// 只负责保存状态;外部只能读不能改(只读快照)
public sealed class TransformMemento
{
public Vector3 Position { get; }
public Quaternion Rotation { get; }
public TransformMemento(Vector3 position, Quaternion rotation)
{
Position = position;
Rotation = rotation;
}
}
Caretaker
public sealed class Checkpoint : MonoBehaviour
{
[SerializeField] private RestorableTransform target;
private TransformMemento _saved; // 保存的快照
// 存档/记录检查点
public void Capture()
{
if (target == null) return;
_saved = target.CreateMemento();
}
// 回档/恢复到检查点
public void Restart()
{
if (target == null || _saved == null) return;
target.Restore(_saved);
}
private void Start()
{
Capture(); // 进场先记一个点(示例)
}
private void Update()
{
// 示例:按 C 存档,按 R 回档
if (Input.GetKeyDown(KeyCode.C)) Capture();
if (Input.GetKeyDown(KeyCode.R)) Restart();
}
}