【GameFramework框架内置模块】1、全局配置(Config)

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

【GameFramework框架】系列教程目录:
https://blog.csdn.net/q764424567/article/details/135831551

这是GameFramework框架内置模块的第一篇,全局配置Config,讲解这些模块的时候会尽量的涉及介绍、为什么使用、如何使用、代码分析这几块,让大家可以知其然,也知其所以然。

二、正文

2-1、介绍

全局配置表,存储了一些游戏中使用的全局的参数配置,比如玩家的初始速度、游戏初始音量等。

全局配置表的结构跟DataTable结构类似,也是列行+键值对,只是没有ID这一列,因为全局配置也不需要用ID去查询, 是直接使用key值进行查询。

2-2、全局配置的作用

全局配置的作用,其实我在介绍里面已经说了,就是存储游戏中使用的全局的参数配置,比如玩家的初始速度、初始蓝量、初始防御力等等。

在实际开发中,也会有这么一个类来存放初始数据,不过通常都需要程序员自己去写这个类存放初始数值,而GF框架已经帮我们封装好了,我们只需要拿来用就可以了。

2-3、全局配置表使用说明

配置文件推荐存放位置

这里我们以官方的StarForce演示项目为例,配置文件都在这里:

说明一下,框架里面是没有GameMain这个文件夹的,这个文件夹是自己的源工程文件的位置,可以放场景、脚本、配置文件等东西。

也就是说,Configs里面放的东西也是自己配置的,下面就说明一下这个文件怎么配置,以及怎么使用的。

配置文件的格式

我们打开一个名字叫做DefaultConfig的默认配置文件:

文件的格式是txt的,内容是个表(比如将json存到一个txt里面,只是为了读取方便,文件格式不重要,重要的里面的内容是怎么读取的)。

先来看一下表结构:

配置项 | 策划备注 | 配置值

OK,了解了表结构,我们来看一下如何快速使用全局配置Config。

(1)首先,我们需要构建一个表,这里用了示例的DefaultConfig.txt的文件:

路径需要记住,需要动态加载。

(2)新建脚本Test01.cs,双击编辑代码:

csharp 复制代码
using StarForce;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test01 : MonoBehaviour
{
    private void Awake()
    {
        LoadConfig();
    }

    private void LoadConfig()
    {
        // 全局配置表路径
        string configAssetName = "Assets/GameMain/Configs/DefaultConfig.txt";
        // 读取
        GameEntry.Config.ReadData(configAssetName, this);
    }

    void Start()
    {
        // 获取GameID
        int GameID = GameEntry.Config.GetInt("Scene.Main");
        Debug.Log(GameID);
    }
}

就Unity持久化数据用法比较类似,实际也就是一回事,只是这个持久化做了封装和统一管理,避免太分散不好管理。

(3)建立流程,运行脚本

这个脚本直接挂载物体上是肯定是不能直接运行的,不符合框架流程

PS:这里再啰嗦一下,这个框架内部有一个自己的运行流程,代码执行顺序,我们使用这个框架的时候,就要避免再使用Unity原来的流程比如Start、Update、Awake,特别是制作流程的时候。

当然,避免使用不是不用,其他不是流程的脚本也可以用Unity的流程

接下来,我们需要制作一个流程,让框架首先去运行这个流程入口,然后流程入口再执行我们的代码。

我们再次打开我们的Test01.cs脚本,修改代码:

csharp 复制代码
using StarForce;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;

public class Test01 : ProcedureBase
{
    public override bool UseNativeDialog => throw new System.NotImplementedException();

    protected override void OnEnter(ProcedureOwner procedureOwner)
    {
        base.OnEnter(procedureOwner);

        LoadConfig();
    }

    protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown)
    {
        base.OnLeave(procedureOwner, isShutdown);
    }

    protected override void OnUpdate(ProcedureOwner procedureOwner, float elapseSeconds, float realElapseSeconds)
    {
        base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);

        // 获取GameID
        int GameID = GameEntry.Config.GetInt("Scene.Main");
        Debug.Log(GameID);
    }

    private void LoadConfig()
    {
        // 全局配置表路径
        string configAssetName = "Assets/GameMain/Configs/DefaultConfig.txt";
        // 读取
        GameEntry.Config.ReadData(configAssetName, this);
    }
}

PS:继承ProcedureBase

使用OnEnter、OnLeave、OnUpdate做状态切换,这里用到了FSM状态机,在另一篇文章有涉及,感兴趣的读者可以翻过去看看:【GameFramework框架】三、快速启动

(4)设置流程启动

将框架中的GameFramework预制体,拖入场景中,挂载GameEntry脚本:

找到流程组件,设置启动流程:

运行程序:

顺利打印。

2-4、代码分析

全局配置组件:

**IConfigManager **

csharp 复制代码
namespace GameFramework.Config;

public interface IConfigManager : IDataProvider<IConfigManager>
{
    //     获取全局配置项数量。
    int Count { get; }
    //     获取缓冲二进制流的大小。
    int CachedBytesSize { get; }
    //     资源管理器。
    void SetResourceManager(IResourceManager resourceManager);
    //     全局配置数据提供者辅助器。
    void SetDataProviderHelper(IDataProviderHelper<IConfigManager> dataProviderHelper);
    //     全局配置辅助器。
    void SetConfigHelper(IConfigHelper configHelper);
    //     要确保二进制流缓存分配内存的大小。
    void EnsureCachedBytesSize(int ensureSize);
    //     释放缓存的二进制流。
    void FreeCachedBytes();
    //     指定的全局配置项是否存在。
    bool HasConfig(string configName);
    //     从指定全局配置项中读取布尔值。
    bool GetBool(string configName);
    //     从指定全局配置项中读取布尔值。
    bool GetBool(string configName, bool defaultValue);
    //     从指定全局配置项中读取整数值。
    int GetInt(string configName);
    //     从指定全局配置项中读取整数值。
    int GetInt(string configName, int defaultValue);
    //     从指定全局配置项中读取浮点数值。
    float GetFloat(string configName);
    //     从指定全局配置项中读取浮点数值。
    float GetFloat(string configName, float defaultValue);
    //     从指定全局配置项中读取字符串值。
    string GetString(string configName);
    //     从指定全局配置项中读取字符串值。
    string GetString(string configName, string defaultValue);
    //     增加指定全局配置项。
    bool AddConfig(string configName, string configValue);
    //     增加指定全局配置项。
    bool AddConfig(string configName, bool boolValue, int intValue, float floatValue, string stringValue);
    //     移除指定全局配置项。
    bool RemoveConfig(string configName);
    //     清空所有全局配置项。
    void RemoveAllConfigs();
}

ConfigData

配置文件解析后存到一个ConfigData类,ConfigData是一个结构体,有四个字段,支持存储4中不同类型的数据:

csharp 复制代码
namespace GameFramework.Config
{
    internal sealed partial class ConfigManager : GameFrameworkModule, IConfigManager
    {
        private struct ConfigData
        {
            private readonly bool m_BoolValue;
            private readonly int m_IntValue;
            private readonly float m_FloatValue;
            private readonly string m_StringValue;
		}
	}
}

所以,当配置表中的数据被读取出来之后,会被同时解析成四种类型,然后构造一个ConfigData进行存储:

csharp 复制代码
/// 增加指定全局配置项。
public bool AddConfig(string configName, string configValue)
{
    bool boolValue = false;
    bool.TryParse(configValue, out boolValue);

    int intValue = 0;
    int.TryParse(configValue, out intValue);

    float floatValue = 0f;
    float.TryParse(configValue, out floatValue);
    
	//把解析的四种类型值全部存入ConfigData
    return AddConfig(configName, boolValue, intValue, floatValue, configValue);
}
/// 增加指定全局配置项。
public bool AddConfig(string configName, bool boolValue, int intValue, float floatValue, string stringValue)
{
    m_ConfigDatas.Add(configName, new ConfigData(boolValue, intValue, floatValue, stringValue));
    return true;
}

之后就是正常的使用了:

csharp 复制代码
//通过Key值:Scene.Main 查询配置
var lastSceneId = GameEntry.Config.GetInt("Scene.Main"));

ConfigComponent提供了四种方式GetInt、GetBool、GetFloat、GetString,获取四种类型的值,但是获取的值需要跟设置的值要相同,不然就获取不到正确的值了。

比如存储Scene.Main值是2,用GetBool获取可能就是默认值false,但是通过GetInt就能获取正确的2。

这么设计的原因可能是为了配置一个字段,但是有可能用到他的不同类型。

比如枚举判断,我们可以用int值,数据乘除计算的时候,可能使用float值。

这样设计用起来就非常灵活了。

三、后记

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏 方向 简介
Unity3D开发小游戏 小游戏开发教程 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶 入门 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUI UGUI Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据 文件读取 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合 数据集合 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发 虚拟仿真 总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件 插件 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发 日常记录 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG 日常记录 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。
相关推荐
LYOBOYI12310 小时前
vscode界面美化
ide·vscode·编辑器
浔川python社11 小时前
关于浔川代码编辑器 v5.0 网页版上线时间的通知
编辑器
浔川python社15 小时前
浔川代码编辑器 v5.0 上线时间公布
编辑器
山峰哥1 天前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
Doro再努力1 天前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
Doro再努力1 天前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
小李也疯狂1 天前
Unity 中的立方体贴图(Cubemaps)
unity·游戏引擎·贴图·cubemap
呆呆敲代码的小Y1 天前
【Unity工具篇】| 超实用工具LuBan,快速上手使用
游戏·unity·游戏引擎·unity插件·luban·免费游戏·游戏配置表
EQ-雪梨蛋花汤1 天前
【Unity优化】Unity多场景加载优化与资源释放完整指南:解决Additive加载卡顿、预热、卸载与内存释放问题
unity·游戏引擎
我的offer在哪里1 天前
用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程
游戏·unity·游戏引擎