基于命令模式的Unity角色切换及按键绑定

基于命令模式的Unity角色切换及按键绑定

目录

  • 基于命令模式的Unity角色切换及按键绑定
    • 前言
    • 开始
    • 一点细节
    • 自定义按键
    • 结语

前言

最近开始看《游戏设计模式》,理解之余,写点东西练练手。

命令模式核心思想:把一个命令看做一个对象。这样做就能让命令拥有所有对象所拥有的优势。

大概意思就是把命令具体化,实例化。这样就可以轻易实现很多的骚操作。比如:
按键自定义(这个就是本文内容)

回合制撤销或回退操作(把命令弄成一个队列,想怎么退怎么退)

宏指令(游戏里面有用这玩意吗?自动战斗组合技?)

新手引导操作(新手引导时响应就是在一个位置点点点,结束之后就改变为具体位置)

简单AI和噩梦AI(命令(技能)是一样的,但是高级AI的内部逻辑会更强大)

还有更多体现。详细解释就不赘述了,网上有很多资料

开始

首先需要一个命令基类,所有命令都会继承这个基类,而命令的执行就是execute函数

public abstract class Commend
{
    public abstract void execute();
}

移动命令

public class MoveCommend : Commend
{
    Unit unit;
    public override void execute()
    {
        unit.move();
    }
}

Unit就是拥有移动move()函数的角色,使用是需要unit赋值。

跳跃命令

public class JumpCommend : Commend
{
    Unit unit;
    public override void execute()
    {
        unit.jump();
    }
}

同上

按钮响应

public class InputHandel : MonoBehaviour
{
    Commend j;//J键
    Commend k;//K键
   
    private void Start()
    {
        j = new MoveCommend();//强制绑定移动命令
        k = new JumpCommend();//强制绑定跳跃命令       
    }

    private void Update()
    {
        inputListen();//每帧监听
    }


    void inputListen()
	{
		//如果按下J键就执行J键对应命令
        if(Input.GetKey(KeyCode.J))
        {
            j.execute();
        }
        else if(Input.GetKey(KeyCode.K))
        {
            k.execute();
        }
    }
}

最后是Unit角色函数,拥有移动和跳跃命令,需要将这个函数绑定在角色物体上

public class Unit : MonoBehaviour
{
    //移动动作
    public void move()
    {
        gameObject.transform.position = gameObject.transform.position + new Vector3(1, 0, 0);
    }

    //跳跃动作
    public void jump()
    {
        gameObject.transform.position = gameObject.transform.position + new Vector3(0, 1, 0);
    }
}

以上就是全部命令模式的内容了(估计会被打死)

我们来加一点点细节

一点细节

首先给基类函数execute加个传入参数GameObject go

public abstract class Commend
{
    public abstract void execute(GameObject go);
}

对应的移动命令变成这样

//移动命令
public class MoveCommend : Commend
{
    Unit unit;
    public override void execute(GameObject go)
    {
        unit = go.GetComponent<Unit>();
        unit.move();
    }
}

之后在按钮响应InputHandel里面加个

 //接受命令的物体
public GameObject go;

然后在Unit里面加个

//使被点击的物体接受命令
private void OnMouseDown()
{
    GetComponentInParent<InputHandel>().go = gameObject;
}

恭喜你,你可以切换接受命令的物体了,只需要在两个物体上分别加上Unit组件,点击一下就对应物体,就会变成对应物体接受命令。当然这样的坏处就是两个物体必须是具有相同命令的。

基于命令模式的Unity角色切换及按键绑定_第1张图片
点击小球,按下j键,小球会移动。再点击长方体,按下j键,就会变成长方体移动。

自定义按键

接下来的工作就是自定义按键。

Unit函数基本没变

因为键盘不可能全部用完,所以需要加一个空命令

public class NullCommend : Commend
{
    public override void execute(GameObject go)
    {
        
    }
}

里面什么也不用写,当这个按键没有作用时,就把这个命令赋给它。

键盘响应函数

public class InputHandel : MonoBehaviour
{
    //26键对应命令数组
    public Commend[] keys = new Commend[26];
    //接受命令的物体
    public GameObject go;
    //改变按钮绑定时关闭按钮响应
    public bool changeTime;

    private void Start()
    {
        //26键初始化
        for(int i=0; i<26; i++)
        {
            keys[i] = new NullCommend();
        }
        keys[9] = new MoveCommend(); //j
        keys[10] = new JumpCommend();//k
        changeTime = true;
    }

    private void Update()
    {
        inputListen();
    }

    //按钮响应
    void inputListen()
    {
        if (changeTime)
        {
            for (int i = 0; i < 26; i++)
            {
                //ASCII码转换成键盘对应按键
                int x = 97 + i;
                char y = (char)x;
                string s = y.ToString();

                if (Input.GetKey(s))
                {
                    //调用对应按键命令
                    keys[i].execute(go);
                }
            }
        }
    }
}

1、需要一个changeTime来确定是否响应,因为输入字母的时候也算按钮响应。
2、start初始化是将j,k默认设置,其他按键就设置为空命令
3、update每帧监听
4、input里面需要将ASCII转化为键盘对应按键。一帧会循环26次,当按下了其中一个按钮时,就会执行对应的命令。

有人会问,在哪切换绑定呢?别急,新建一个UI输入需要的按键
基于命令模式的Unity角色切换及按键绑定_第2张图片
点击改变按钮时,之前设置的changeTime就有用武之地了,将它毫不留情的设置为false。暂停按钮监听,然后在两个文本框里输入需要的按键。最后点击确定,大功告成。

UI函数

public class UI : MonoBehaviour
{
    public GameObject  move;
    public GameObject jump;
    public InputHandel inputHandel;
    char[] moveButton;
    char[] jumpButton;

    //从文本框读取字母,并添加功能
    public void change()
    {
        moveButton = move.GetComponent<InputField>().text.ToCharArray();
        jumpButton = jump.GetComponent<InputField>().text.ToCharArray();

        int i = (int)moveButton[0];
        int j = (int)jumpButton[0];

        if (i>=65 && i<=90)
        {
            i -= 65;
        }
        else
        {
            i -= 97;
        }
        if(j>=65 && j<=90)
        {
            j -= 65;
        }
        else
        {
            j -= 97;
        }
   
        //Debug.Log("i:" + i + "j:" + j);

        //将命令赋予对应的keys[i]
        for(int x=0; x<26; x++)
        {
            if(x == i)
            {
                inputHandel.keys[i] = new MoveCommend();
            }
            else if(x == j)
            {
                inputHandel.keys[j] = new JumpCommend();
            }
            else
            {
                inputHandel.keys[x] = new NullCommend();
            }
        }

        inputHandel.changeTime = true;
    }

    //暂定按钮响应
    public void startChange()
    {
        inputHandel.changeTime = false;
    }	
}

1、 Char存储对应的字母,因为ASCII限制所以只能绑定A-Z 26个按键,当然是大小写都能势识别的
2、 赋予命令的时候注意需要将有用的赋予功能,没有用的按键需要设置为空命令,否则会功能冲突,因为一开始已经全部都设置过空,所以不会报空错误。

结语

以上就是基于命令模式的unity角色切换及按键绑定的全部内容了,第一次写这种技术向文章,不足之处还请见谅。

最后推荐一波资料出处游戏设计模式。再次感谢您的阅读。

你可能感兴趣的:(基于命令模式的Unity角色切换及按键绑定)