command命令模式(三)_C#

本文深入探讨了命令模式在游戏开发中的应用,通过Unity框架实现了角色控制的命令模式,支持多个角色的选择与控制,同时引入了撤销命令的功能,提高了游戏的交互性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
        }
    }
}

这里加了一个键的数组,我们只要更改数组对应位置的键,就可以实现改建啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值