首页 > 其他分享 >(自用)基于unity的指令(命令)模式

(自用)基于unity的指令(命令)模式

时间:2023-12-02 23:57:14浏览次数:29  
标签:void 玩家 unity 指令 自用 操作 KeyCode public

指令模式

1.配置输入

  所有游戏中都包含玩家输入指令的部分(这些部分通常写在游戏循环中 如unity中的UpData() ) 游戏会每一帧都进行一次读取,当玩家按下相应按键时 则会进行对应方法
  为了可以时刻检测并记录玩家进行的操作,或者对某个对应的操作的指令进行更改,我们需要将这些输入封装为一个类似于变量的对象

  1. 定义一个基类代表游戏中可触发的行为
public Interface Command
{
    public void excute(){}

}
  1. 为不同游戏行为定义相应子类
public class JumpCommand : Command
(
    public void excute()
    {
        jump();
    }
)
public class FireCommand : Command
{
    public void excute()
    {
        Fire();
    }
}


  1. 在代码部分对定义的子类进行实例化 并放入输入部分
public class InputHandler
{
    JumpCommand jumpCommand;
    jumpCommand = new JumpCommand(){};
    FireCommand fireCommand;
    fireCommand = new fireCommand(){};
    if(Input.GetKeyDown(KeyCode.X))
    {
        jumpCommand;
    }
    else if(Input.GetKeyDown(KeyCode.Y))
    {
        fireCommand;
    }
}


相比起直接将控制内容写入游戏循环 在新的代码中 玩家每进行一次输入 都会访问一次对应的指令类

2.用户类

  当我们已经进行了一些操作时,需要对游戏中的某些对象进行操作 大部分情况是玩家所控制的角色,但有时需要改变角色类型或是更广泛的内容 在这种情况下 需要我们对游戏中的对象进行进一步封装,当玩家进行操作时,游戏内会对对象发出一定命令流 并找到接收命令的对象 再执行相关操作

public class Singleton<T>where T : MonoBehaviour
{
    protected Singleton(){};
    private static T _inst = null;
    public static T instance => _inst ?? (_inst = new T());
    public static void Clear()
   {
    _inst = null;
   }

}

首先我们要单例化指令类

public class JumpCommand : Command , Singleton<JumpCommand>
{
    void Excute()
    {
        //执行跳跃(执行的函数中包含对接收者的操作)
    }

}
public class FireCommand : Command , Singleton<FireCommand>
{
    void Excute()
    {
        //执行操作(执行的函数中包含对接收者的操作)
    }

}

在用户类中引用指令类

public class User : MonoBehaviour 
{
    GameObject Player =new GameObject(); //实例化接收者类
    public void Jump()
    {
        if(Input.GetKeyDown(KeyCode.R))
        {
            JumpCommand.instance.Excute();
        }
    }
    public void Fire()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {
            FireCommand.instance.Excute();
        }
    }

}


最后在游戏循环中检测玩家操作

public void Start()
{
    User user1 = new User();
}
public void UpData()
{
    user1.Jump();
    user1.Fire();
}


通过这种方式,我们就可以更加灵活地更改玩家操作的内容和操作的对象 并且我们也可以使用AI代码对一些对象进行自动操作

3.指令撤销与重做

  当玩家进行一个更改操作之后 需要回到更改之前的状况 如果我们每帧都记载一次游戏的状况 然后当玩家按下返回按键时回到上一次记载的状况时 会导致游戏中出现大量的内存占用 但当我们在指令类中记录玩家的每次操作 当玩家按下返回按键时 只需要返回上一次操作即可 就可以大大降低内存占用并且达到返回指令的效果

  1. 首先我们在指令类中加入返回操作
public Interface Command
{
    public void Excute(){}
    public void UnExcute(){}
}


  1. 在控制类中完成返回操作
public class JumpCommand : Command 
{
    void Excute()
    {
        //执行跳跃(执行的函数中包含对接收者的操作)
    }
    void UnExcute()
    {
        //返回操作(返回操作中包含玩家执行操作前的数据)
    }

}
public class FireCommand : Command 
{
    void Excute()
    {
        //执行操作(执行的函数中包含对接收者的操作)
    }
    void UnExcute()
    {
        //返回操作(返回操作中包含玩家执行操作前的数据)
    }
}


  1. 在用户类中进行返回操作
public class User : MonoBehaviour 
{
    GameObject Player =new GameObject(); //实例化接收者类  

    int jumpCurrent = 0; //记录操作的次数
    int FireCurrent = 0; //记录操作的次数

    List<JumpCommand> jumpList = new List<JumpCommand>();
    //定义对应指令的列表 来储存当前指令的次数和本次指令中玩家的状态  
    List<FireCommand> fireList = new List<FireCommand>();
    //定义对应指令的列表 来储存当前指令的次数和本次指令中玩家的状态  

    public void Jump()
    {
        if(Input.GetKeyDown(KeyCode.R))
        {
            jumpCurrent++;  
            JumpCommand newJump = jumpList[jumpCurrent];
            newJump.Excute();
        }
        if(Input.GetKeyDown(KeyCode.Ctrl) && Input.GetKeyDown(KeyCode.R))
        {
            jumpCurrent--;
            jumpCommand reJump = jumpList[jumpCurrent];
            reJump.UnExcute();
        }
    }
    public void Fire()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {
            fireCurrent++;
            FireCommand newFire = fireList[fireCurrent];  
            newFire.Excute(); 
        }
        if(Input.GetKeyDown(KeyCode.Ctrl) && Input.GetKeyDown(KeyCode.F))
        {
            fireCurrent--;
            fireCommand reFire = fireList[fireCurrent];
            reFire.UnExcute();
        }
    }

}    
 

最后在游戏循环中检测玩家操作

void Start()
{
    User user1 = new User();
}
void UpData()
{
    user1.Jump();
    user1.Fire();
}

标签:void,玩家,unity,指令,自用,操作,KeyCode,public
From: https://www.cnblogs.com/ShineLightYiyi/p/17872485.html

相关文章

  • 使用unity开发Pico程序,场景中锯齿问题
    1、问题使用unity【非HDR】开发Pico程序,场景中锯齿问题,设置了unity的抗锯齿和渲染方式,及悬挂抗锯齿的脚本,都不能很好的解决项目中图片、文字的锯齿问题,通过摸索找到了妥善的方法1、修改项目中图片的GenerateMIpMaps为勾选状态,MipMapsPreserveCoverage这个可以未勾选,若是勾选......
  • Unity实现的行为树
    游戏AI行为决策——行为树前言行为树,是目前游戏种应用较为广泛的一种行为决策模型。这离不开它成熟的可视化编辑工具,例如Unity商城中的「BehaviourDesigner」,甚至是虚幻引擎也自带此类编辑工具。而且它的设计逻辑并不复杂,其所利用的树状结构,很符合人的思考方式。接下来,我们会......
  • Unity builtin GUIStyle内置样式
    https://gist.github.com/bikrone/666bb26fb0d4468df12c890ecc6c512eusingUnityEditor;usingUnityEngine;publicsealedclassExampleClass:EditorWindow{privatestaticreadonlystring[]mList={"AboutWIndowLicenseLabel"......
  • Unity学习笔记--数据持久化XML文件(2)
    IXmlSerializable接口:使用该接口可以帮助处理不能被序列化和反序列化的特殊类得到处理,使特殊类继承IXmlSerializable接口,实现其中的读写方法,检测到读写方法被重写之后,便会按照自定义实现的接口来实现方法。usingSystem;usingSystem.IO;usingSystem.Runtime.InteropServi......
  • 如何拆解Unity 2022.3版本的AssetBundle
    1)如何拆解Unity2022.3版本的AssetBundle2)Unity2022LTS版本的稳定性3)关于AssetBundle禁用TypeTree之后的一些可序列化的问题这是第363篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。UWA社区主页:community.......
  • Unity2D中瓦片地图的创建与绘制教程
    Unity2D中瓦片地图的创建与绘制素材切割创建地图创建瓦片绘制地图瓦片调色板画笔拓展素材资源链接素材切割选中以下素材,以Tiles为例(素材链接在文章最下方)修改素材属性。将SpriteMode属性改为Multiple多张(不然切割不了);PixelsPerUnit改为16像素;FilterMode改为Point(nofilte......
  • Unity3D角色移动控制脚本
    Unity3D角色移动控制脚本键盘控制方向鼠标控制方向键盘控制方向privateCharacterControllercontroller;publicfloatSpeed=1f;publicfloatRotateSpeed=1f;voidStart(){ controller=transform.GetComponent<CharacterController>();}voidUpdate(){ //键盘......
  • 普通unity项目升级URP管线渲染项目教程
    普通unity项目升级URP管线渲染安装URP插件创建URP渲染管线配置渲染管线升级素材的渲染管线方式一方式二资源链接安装URP插件点击Window选择PackageManager在出现的窗口左上角选择UnityRegistry搜索关键字Universal在出现的UniversalRP插件中下面点击Install创建URP渲染管线安......
  • jenkins使用shell提交git指令时,怎么使用 credential凭证信息
    在Jenkins中使用shell脚本提交Git指令时,你可以通过使用Git凭据信息来进行认证。这可以通过以下步骤来实现:设置Git凭据:在Jenkins中,你可以在“凭据”(Credentials)中添加Git的用户名和密码。在Jenkins主界面,点击“凭据”->“系统”->“全局凭据”->“添加凭据”,然......
  • 使用Unity Localization插件进行项目本地化实战详解
    在使用Unity开发游戏的过程中,本地化是必不可少的。网络上也有很多的本地化工具,本次我介绍的是Unity官方提供的Localization插件,大家可以在PackageManager进行安装 一、语言配置,本地化表创建在ProjectSetting中找到Localization,(需要先创建这个LocalizationSetting文件)点击L......