Unity3D设计模式之命令模式

来源:互联网 发布:淘宝毕业论文多少钱 编辑:程序博客网 时间:2024/06/05 06:49

类图:

这里写图片描述

理解:

一条命令的周期为发布和接受(执行)。在Unity3D中,
调用者(Invoker)一般为控制器或者角色本身,得到客户端输入,调用具体的命令发布出去。
接受者(Receiver)(说成执行者可能更好理解),一般为角色本身,提供一些命令的具体执行方法。

在传统的Unity3D中,通过按键控制物体,一般是以
if(Input.GetKey(KeyCode.W)){
//向前移动的具体逻辑
}

上面的代码看似非常正常,但是这里的调用模块和执行模块高耦合,调用者需要关心者接受者的逻辑实现,执行者需要根据具体的调用来实现逻辑,两者过于相互依赖。如果那天需要修改向前移动的逻辑,或者更换向前移动的按键,需要直接修改上面的代码具体逻辑。违反了开闭原则。或者需要更换控制角色,则就需要更换脚本绑定。

命令模式主要的特点是把调用者和接受者之间的连接——命令——类化,把命令(Command)独立出来一个,成为一个单独的层用来连接调用者和接受者。然后调用者(Invoker)调用命令,命令通知接受者(Receiver)具体的执行逻辑

实际使用:

这里通过WSAD键控制Cube的前后左右移动的例子实现命令模式在Unity3D中的使用

ICommand.cs:

using UnityEngine;using System.Collections;public interface ICommand {    void Execute(Receiver receiver);}

命令接口(由于会存在多个不同的命令,这里将命令的公共部分写成接口),其中Receiver是接受者(执行者),用于调用接受者的具体执行方法
——————————————————————————————————————————————————————

MoveCommand.cs

using UnityEngine;using System.Collections;public class MoveForwardCommand : ICommand {    public void Execute(Receiver receiver){        receiver.MoveForward();    }}public class MoveBackCommand : ICommand {    public void Execute(Receiver receiver){        receiver.MoveBack();    }}public class MoveLeftCommand : ICommand {    public void Execute(Receiver receiver){        receiver.MoveLeft();    }}public class MoveRightCommand : ICommand {    public void Execute(Receiver receiver){        receiver.MoveRight();     }}

4个具体的命令类,实现了ICommand接口。
——————————————————————————————————————————————————————
Receiver.cs:

using UnityEngine;using System.Collections;public class Receiver : MonoBehaviour {    public float speed = 6f;    CharacterController characterController;    Vector3 moveDir = Vector3.zero;    void Awake(){        characterController = GetComponent<CharacterController>();    }    public void MoveForward(){        moveDir = transform.TransformDirection(Vector3.forward) * speed; //将世界的正前方向量转化为物体的正前方向量        characterController.Move(moveDir * Time.deltaTime);    }    public void MoveBack(){        moveDir = transform.TransformDirection(Vector3.back) * speed;        characterController.Move(moveDir * Time.deltaTime);    }    public void MoveRight(){        moveDir = transform.TransformDirection(Vector3.right) * speed;        characterController.Move(moveDir * Time.deltaTime);    }    public void MoveLeft(){        moveDir = transform.TransformDirection(Vector3.left) * speed;        characterController.Move(moveDir * Time.deltaTime);    }}

这里提供了具体的移动逻辑方法,这里通过CharacterController进行移动
——————————————————————————————————————————————————————

这里写图片描述

在Unity3D项目中创建一个Plane做背景,创建一个Cube和Sphere作为被控制移动的对象,GameController是一个空物体,用作控制移动脚本的载体。

这里写图片描述
给Cube和Sphere添加CharacterController组件和Receiver脚本

这里写图片描述
给GameController添加Invoker脚本

分别将Cube和Sphere拖给Invoker脚本的Receiver,分别运行,Receiver为Cube时,可以控制Cube移动,Receiver是Sphere时,可以控制Sphere移动。

总结

命令模式将调用模块和接受模块进行了很大程度的解耦,利于扩展。

学疏才浅,理解有限,欢迎指正不对之处,共同交流

原创粉丝点击