http://gameprogrammingpatterns.com/
本篇命令模式基于《 Game Programming Patterns》加入了点个人理解,代码有点多
首先依然是一个Command基类
public abstract class Command {
protected float _TheTime;
public float TheTime
{
get { return _TheTime; }
}
public virtual void execute(character mycharacter) { }
public virtual void undo(character mycharacter) { }
}
然后是一个角色的基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class character : MonoBehaviour {
private Transform transform1;
public Transform Transform
{
get
{
return transform1;
}
set
{
transform1 = value;
}
}
// Use this for initialization
public abstract void Start();
public abstract void move(Vector3 dir);
}
为什么有一个角色的基类,大家都玩过不少游戏吧,我们很多时候并不是单单控制一个角色移动,所以这里做了一个角色的基类,意味着这次我们可以选择接收命令的角色。
两个角色子类
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : character {
public override void move(Vector3 dir)
{
transform.Translate(dir);
}
public override void Start()
{
Transform = this.transform;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Avatar : character {
public override void move(Vector3 dir)
{
transform.Translate(dir);
}
public override void Start()
{
Transform = this.transform;
}
}
接着是命令和接收者的绑定
using UnityEngine;
public class CommandMove : Command {
private Vector3 TransPos;
private character mycharacter;
public CommandMove(character character,Vector3 transPos, float time)
{
mycharacter = character;
TransPos = transPos;
_TheTime = time;
}
public override void execute(character mycharacter)
{
mycharacter.move(TransPos);
}
public override void undo(character mycharacter)
{
mycharacter.move(-TransPos);
}
}
最后是命令的具体发布
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 角色
/// </summary>
public enum myCharacter
{
avater,
enemy
}
public class CommandManager : MonoBehaviour
{
//可以改键啦
private KeyCode[] key = new KeyCode[] { KeyCode.W,KeyCode.S,KeyCode.A,KeyCode.D};
public Avatar avater;
public Enemy enemy;
private character m_character;//私有控制对象
private Stack<Command> mCommandStack;
private float mCallBackTime;
public bool IsCommanding = true;//true则执行命令,false撤销命令
public myCharacter _character;//选择一个执行对象
// Use this for initialization
void Start()
{
mCommandStack = new Stack<Command>();
mCallBackTime = 0;
m_character = setCharacter(_character);
}
private character setCharacter(myCharacter cha)
{
switch (cha)
{
case myCharacter.avater:
return avater;
case myCharacter.enemy:
return enemy;
default:
Debug.LogError("Unknown character");
return avater;
}
}
// Update is called once per frame
void Update()
{
if (IsCommanding)
{
Control();
}
else
{
RunCallBack();
}
}
//根据时间撤销命令
private void RunCallBack()
{
mCallBackTime -= Time.deltaTime;
if (mCommandStack.Count > 0 && mCallBackTime < mCommandStack.Peek().TheTime)
{
mCommandStack.Pop().undo(m_character);
}
}
private Command InputHandler(character m_character)
{
if (Input.GetKey(key[0]))
{
return new CommandMove(m_character, new Vector3(0, Time.deltaTime, 0), mCallBackTime);
}
if (Input.GetKey(key[1]))
{
return new CommandMove(m_character, new Vector3(0, -Time.deltaTime, 0), mCallBackTime);
}
if (Input.GetKey(key[2]))
{
return new CommandMove(m_character, new Vector3(-Time.deltaTime, 0, 0), mCallBackTime);
}
if (Input.GetKey(key[3]))
{
return new CommandMove(m_character, new Vector3(Time.deltaTime, 0, 0), mCallBackTime);
}
return null;
}
private void Control()
{
Command cmd = InputHandler(m_character);
if (cmd != null)
{
mCallBackTime += Time.deltaTime;
mCommandStack.Push(cmd);
cmd.execute(m_character);
}
}
}
这里加了一个键的数组,我们只要更改数组对应位置的键,就可以实现改建啦