Unity3D设计模式之命令模式

类图:

这里写图片描述

理解:

一条命令的周期为发布和接受(执行)。在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移动。

总结

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值