首页 > 编程语言 >FSM状态机及C#反射实现逻辑

FSM状态机及C#反射实现逻辑

时间:2024-03-16 11:44:07浏览次数:14  
标签:状态 string Dictionary C# FSM 状态机 new line

零、大致逻辑

1.初始化 Start

组件->状态->状态内部初始化->进入初始状态

2.运行时 Update

遍历状态的所有条件->

不满足所有条件对象->执行当前状态运行时逻辑->进行一次玩家搜索

满足某一个条件对象->执行当前状态退出逻辑->执行状态改变->执行新状态进入逻辑->执行新状态运行时逻辑->进行一次玩家搜索

3.销毁时 OnDestroy

清空所有状态内部数据->清空状态机数据->清空所有状态

一、状态机配置文件和它的工厂

状态机需要知道当前对象会有哪些状态,且状态需要知道有哪些条件

并以Dictionary<状态, Dictionary<条件, 目标状态>>存到状态机内部

状态机填一个文件名,数据以txt方式存在于StreamAsset文件夹下

使用反射,将这一个个字符串变成状态类和条件类

那么,该如何去拿到这些字符串呢

我们使用一个工厂,状态机传字符串给工厂

工厂看看自己的缓存中有没有,有就给你,没有就new

下方的类就和一个字符串相匹配Dictionary<string, FSMConfigFlie>

状态机配置文件初始化

public class FSMConfigFlie
{
    public Dictionary<string, Dictionary<string, string>> Map;
    private string current = "";
    
    //这是供工厂使用的文件读取方法
    public FSMConfigFlie(string fileName)
    {
        Map = new Dictionary<string, Dictionary<string, string>>();
        BuildMap(ConfigFile.GetConfigFile(fileName), MyBuildMap);
    }
    
    //这是其他地方写的享元函数,但由于篇幅太大,就直接提过来了
    private void BuildMap(string paths,Action<string> handler)
    {
        using (StringReader reader = new StringReader(paths))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                handler(line);
            }
        }
        //StringReader是个数据流,在使用完毕后要关闭,倘若中途出错,就不会关了
        //但是用using括起来,那么只要它运行完毕, 肯定关了。
    }

    //详细解析
    private void MyBuildMap(string line)
    {
        if (line.StartsWith("["))
        {
            current = line.Substring(1, line.Length - 2);
            Map.Add(current, new Dictionary<string, string>());
        }
        else if (line.Contains(">"))
        {
            string[] keyValue = line.Split('>');
            Map[current].Add(keyValue[0], keyValue[1]);
        }
    }
}
配置文件Map缓存
 public class FSMConfigFlieFactory
{
    //缓存
    public static Dictionary<string, FSMConfigFlie> OMap;
    
    //静态变量
    static FSMConfigFlieFactory()
    {
        OMap = new Dictionary<string, FSMConfigFlie>();
    }
    
    //供外部使用的状态数据获取方法
    public static Dictionary<string, Dictionary<string, string>> GetMap(string file)
    {
        if (!OMap.ContainsKey(file))
        {
            OMap.Add(file, new FSMConfigFlie(file));
        }
        return OMap[file].Map;
    }
}

此时,我们就获得了

Dictionary<状态, Dictionary<条件, 目标状态>>

二、状态抽象类

然后,就是状态类,拿到Dictionary<状态, Dictionary<条件, 目标状态>>中的Value

三、条件抽象类

四、FSMBase代码

标签:状态,string,Dictionary,C#,FSM,状态机,new,line
From: https://www.cnblogs.com/LateUpdate/p/18076827

相关文章

  • golang select底层原理
    select语句在Go语言中用于在多个通信操作(发送和接收)之间进行选择。在底层,Go运行时维护了关于每个case的状态信息,这些信息通常存储在scase结构体中。下面我将详细解释select语句的工作原理,并尝试用文字描述来模拟这一过程,因为直接在这里画图可能不太方便。首先,让我们回......
  • CF1923D. Slimes
    Problem-1923D-Codeforces现在怎么菜成这样了aaaaaaa我们考虑枚举\(i\),则到底是谁吃掉了\(i\)不重要(我思考的时候就因为这个没有想到正解)\(i\)的后缀反着跑一边即可,因此只考虑\(i\)前缀把他吃掉的情况发现就是找一段最短的前缀的后缀和使区间里的和\(>......
  • Docker - 部署禅道
    原文链接:https://mp.weixin.qq.com/s/8L0Rv6Wc0lFsQU6Lw0QloQ   简单的看了一下原文,他使用的是Ubuntu的操作系统,第一步的Docker安装相关命令我确实没有使用过。不过对Linux熟悉的话,那些命令也不难理解。我的是Centos7.5安装的docker,可以参照我的其他博文或者自行百度。接下......
  • 【C语言初阶(五)】数组
    ❣博主主页:33的博客❣▶文章专栏分类:C语言从入门到精通◀......
  • GDCM:实现读取DICOM属性并打印(附完整源码)
    GDCM:实现读取DICOM属性并打印下面是一个使用GDCM库读取DICOM文件属性并打印它们的示例代码:#include<iostream>#include"gdcmReader.h"#include"gdcmFile.h"#include"gdcmDataSet.h"#include"gdcmAttribute.h"intmain(intargc,char*argv[])......
  • 使用docker-compose管理freeswitch容器
     概述之前的文章我们介绍过如何将freeswitch做成docker镜像,也使用命令行模式正常启动了fs的docker容器。但是当我们需要同时管理多个docker容器的时候,还是使用docker-compose更简单。环境CENTOS7dockerengine:Version25.0.3DockerComposeversionv2.24.6centosdock......
  • Spring Schedule定时任务进阶篇(调度器)
    SpringSchedule背后支持多种任务调度方案,如JDKTimer、concurrent包下的ScheduledExecutorService以及Quartz等。Spring通过封装这些底层实现,为开发者提供了统一的接口和配置方式来处理定时任务。接下来通过SpringBoot+数据库来实现根据数据库数据来动态管理我们的定时任务,我这......
  • lc2426 满足不等式的数对个数
    给定两个大小为n的数组nums1和nums2以及整数diff,统计满足以下条件的数对(i,j)的个数:0<=i<j<=n-1,并且nums1[i]-nums1[j]<=nums2[i]-nums2[j]+diff。2<=n<=1e5;-1e4<=nums1[i],nums2[i]<=1e4;-1e4<=diff<=1e4先对条件做下变形,将下标相同的移到同一侧,得到:nums1[i]-nums2[i]<=nums......
  • C语言项目工程目
    1.文件类型头文件(HeaderFiles):通常以.h作为扩展名,头文件包含了程序中所需要的各种函数、变量、宏定义等的声明,以及各种库函数的引用等源文件(SourceFiles):通常以.c作为扩展名,源文件包含了程序的实现代码库文件(LibraryFiles):库文件是一些预编译好的对象文件的集合,包......
  • LibreOJ 3591 「USACO 2018.02 Platinum」Cow Gymnasts
    以\(0\)为初始下标。考虑到这个平台之间的转移不是很好处理,于是考虑换个角度,考虑每个高度。这里定义高度为\(i\)的奶牛就是下一次操作要走\(i\)步的奶牛。然后考虑去分析合法序列的性质。性质\(1\):高度为\(x\)的奶牛在移动后的高度依然为\(x\),即这个过程可以看作每......