接口
public interface Command
{
void Execute();
void UnExecute();
}
命令的具体实现
using UnityEngine;
// 命令类型的枚举
public enum MoveDirection { up, down, left, right };
/// <summary>
/// 命令的具体实现
/// </summary>
class MoveCommand : Command
{
private MoveDirection _direction;//命令类型
private MoveCommandReceiver _receiver;//拿到执行者
private float _distance;
private GameObject _gameObject;//命令的具体体现
//构造命令
public MoveCommand(MoveCommandReceiver reciever, MoveDirection direction, float distance, GameObject gameObjectToMove)
{
this._receiver = reciever;
this._direction = direction;
this._distance = distance;
this._gameObject = gameObjectToMove;
}
//执行
public void Execute()
{
_receiver.MoveOperation(_gameObject, _direction, _distance);
}
//撤销
public void UnExecute()
{
_receiver.MoveOperation(_gameObject, InverseDirection(_direction), _distance);
}
//命令的撤销处理
private MoveDirection InverseDirection(MoveDirection direction)
{
switch (direction)
{
case MoveDirection.up:
return MoveDirection.down;
case MoveDirection.down:
return MoveDirection.up;
case MoveDirection.left:
return MoveDirection.right;
case MoveDirection.right:
return MoveDirection.left;
default:
Debug.LogError("Unknown MoveDirection");
return MoveDirection.up;
}
}
//重写string
public override string ToString()
{
return _gameObject.name + " : " + MoveDirectionString(_direction) + " : " + _distance.ToString();
}
public string MoveDirectionString(MoveDirection direction)
{
switch (direction)
{
case MoveDirection.up:
return "up";
case MoveDirection.down:
return "down";
case MoveDirection.left:
return "left";
case MoveDirection.right:
return "right";
default:
return "unkown";
}
}
}
命令执行者
/// <summary>
/// The 'Receiver' class - this handles what a move command actually does
/// </summary>
using UnityEngine;
class MoveCommandReceiver
{
public void MoveOperation(GameObject gameObjectToMove, MoveDirection direction, float distance)
{
switch (direction)
{
case MoveDirection.up:
MoveY(gameObjectToMove, distance);
break;
case MoveDirection.down:
MoveY(gameObjectToMove, -distance);
break;
case MoveDirection.left:
MoveX(gameObjectToMove, -distance);
break;
case MoveDirection.right:
MoveX(gameObjectToMove, distance);
break;
}
}
private void MoveY(GameObject gameObjectToMove, float distance)
{
Vector3 newPos = gameObjectToMove.transform.position;
newPos.y += distance;
gameObjectToMove.transform.position = newPos;
}
private void MoveX(GameObject gameObjectToMove, float distance)
{
Vector3 newPos = gameObjectToMove.transform.position;
newPos.x += distance;
gameObjectToMove.transform.position = newPos;
}
}
命令发布者
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 命令发布者
/// </summary>
public class InputHandler : MonoBehaviour
{
public float moveDistance = 10f;
public GameObject objectToMove;//具体实现者
private MoveCommandReceiver moveCommandReciever;//执行者
private List<MoveCommand> commands = new List<MoveCommand>();//命令列表
private int currentCommandNum = 0;//当前命令数量
void Start()
{
moveCommandReciever = new MoveCommandReceiver();
if (objectToMove == null)
{
Debug.LogError("objectToMove must be assigned via inspector");
this.enabled = false;
}
}
//撤销命令的包装
public void Undo()
{
if (currentCommandNum > 0)
{
//撤销当前最后一条命令
MoveCommand moveCommand = commands[--currentCommandNum];
moveCommand.UnExecute();
}
}
public void Redo()
{
if (currentCommandNum < commands.Count)
{
//执行当前的下一条命令
MoveCommand moveCommand = commands[currentCommandNum++];
moveCommand.Execute();
}
}
private void Move(MoveDirection direction)
{
MoveCommand moveCommand = new MoveCommand(moveCommandReciever, direction, moveDistance, objectToMove);
moveCommand.Execute();
commands.Add(moveCommand);
currentCommandNum++;
}
//命令
public void MoveUp() { Move(MoveDirection.up); }
public void MoveDown() { Move(MoveDirection.down); }
public void MoveLeft() { Move(MoveDirection.left); }
public void MoveRight() { Move(MoveDirection.right); }
//显示
void OnGUI()
{
string label = " start";
if (currentCommandNum == 0)
{
label = ">" + label;
}
label += "\n";
for (int i = 0; i < commands.Count; i++)
{
if (i == currentCommandNum - 1)
label += "> " + commands[i].ToString() + "\n";
else
label += " " + commands[i].ToString() + "\n";
}
GUI.Label(new Rect(0, 0, 400, 800), label);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
MoveUp();
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
MoveDown();
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
MoveLeft();
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
MoveRight();
}
if (Input.GetKeyDown(KeyCode.R))
{
Redo();
}
if (Input.GetKeyDown(KeyCode.U))
{
Undo();
}
}
}