3.3配置表加载和读取
CGGG edited this page Jun 23, 2021
·
4 revisions
在本游戏里,我们使用一个数据集
来对游戏中的角色数值、武功数值、地图等等来进行集中配置,这个数据集我们把它称为配置表
。
本项目配置表使用excel来进行管理,每个excel对应一个种类的配置,excel目录位于jyx2\excel
工作原理概述:
在开发项目时,开发人员可以直接打开excel进行编辑,而后通过本项目提供的工具将excel的内容生成为可被游戏读取的数据(菜单项:配置表/[GEN DATA])。在游戏启动时将统一对数据进行读取载入,游戏运行过程中,代码可以访问到配置表中的各项数据。
本项目配置表管理框架使用 HSFramework,存放的目录结构如下:
- jyx2/excel 配置表目录
- jyx2/reg 映射文件目录(每个xml对应一个excel文件,中间通过语法描述了生成XML的规则)
- jyx2/Assets/Scripts/Jyx2Pojos 对应的绑定代码,我们将每个配置表映射到的一份数据结构成为Pojo(需要继承自BaseBean),数据结构到字段的映射通过xml标签进行绑定
一个典型的reg样例
<?xml version="1.0" encoding="utf-8"?>
<bean name="jyx2skill" from="JYX2武功.xlsx" to="jyx2skill.xml" >
<variable name="Id" fromCol="代号" type="string" />
<variable name="Name" fromCol="名称" type="string" />
<variable name="SoundEffect" fromCol="出招音效" type="int" />
<variable name="SkillType" fromCol="武功类型" type="int" />
<variable name="Animation" fromCol="武功动画音效" type="int" />
<variable name="DamageType" fromCol="伤害类型" type="int" />
<variable name="SkillCoverType" fromCol="攻击范围" type="int" />
<variable name="MpCost" fromCol="消耗内力点数" type="int" />
<variable name="Poison" fromCol="敌人中毒点数" type="int" />
<variable fromIndex="1" endIndex="10" type="collection" >
<bean name="SkillLevels">
<variable name="Attack" notNull="true" fromCol="[index]级攻击力" type="int" />
<variable name="SelectRange" fromCol="[index]级移动范围" type="int" />
<variable name="AttackRange" fromCol="[index]级杀伤范围" type="int" />
<variable name="AddMp" fromCol="[index]级加内力" type="int" />
<variable name="KillMp" fromCol="[index]级杀伤内力" type="int" />
</bean>
</variable>
</bean>
GENDATA工作流程
excel(GEN DATA) -> xml(反序列化) -> C# Pojo类实例(protobuf序列化) -> 二进制数据,保存在
Assets/StreamingAssets
下
运行时读取流程
二进制(protobuf反序列化) -> C# Pojo类实例
概念补充说明
- protobuf:由google公司提供的高性能序列化/反序列化框架。
- 使用到的XML序列化/反序列化标签
- 每一个excel对应一个reg文件,用来描述如何将excel转成xml
- 每一个reg文件同时对应一个C# Pojo类(绑定关系在ConfigTableInitHelperShared.cs中定义,样例如下)
using System;
using HSFrameWork.ConfigTable;
using System.Collections.Generic;
using Jyx2;
namespace Jyx2.Crossplatform.BasePojo
{
/// <summary>
/// 客户端和服务端必须共享此实现,否则Values可能会无法正常加载。
/// </summary>
public abstract class ConfigTableInitHelperShared : DefaultInitHelper
{
public override IEnumerable<Type> ProtoBufTypes { get { return _SharedTypes; } }
public override bool ShowExeTimer { get { return true; } }
/// <summary>
/// 服务端和客户端共同需要二进制序列化的类
/// </summary>
protected static readonly List<Type> _SharedTypes = new List<Type>(){
//client
typeof(GameMap),
typeof(System.Numerics.Vector3),
typeof(System.Numerics.Vector2),
//jyx2
typeof(Jyx2Role),
typeof(Jyx2Map),
typeof(Jyx2Item),
typeof(Jyx2Skill),
typeof(Jyx2RoleHeadMapping),
typeof(Jyx2RoleWugong),
typeof(Jyx2RoleItem),
typeof(Jyx2SkillLevel),
typeof(Jyx2SkillDisplay),
typeof(Jyx2Battle),
typeof(Jyx2IntWrap),
typeof(Jyx2Shop),
typeof(Jyx2ShopItem),
};
/// <summary>
/// 将XML文件中的NODE和实际的POJO Class进行关联。请注意:InitBind的顺序和添加的顺序相同。
/// </summary>
protected override void BuildTypeNodes()
{
AddTypeNode<GameMap>("gamemap");
//jyx2
AddTypeNode<Jyx2Role>("jyx2role");
AddTypeNode<Jyx2Map>("jyx2map");
AddTypeNode<Jyx2Item>("jyx2item");
AddTypeNode<Jyx2Skill>("jyx2skill");
AddTypeNode<Jyx2RoleHeadMapping>("jyx2role_headMapping");
AddTypeNode<Jyx2SkillDisplay>("jyx2skillDisplay");
AddTypeNode<Jyx2Battle>("jyx2battle");
AddTypeNode<Jyx2Shop>("jyx2shop");
}
}
}
你可以在游戏运行中使用 ConfigTable.Get<T>(key)
等函数来获取excel中定义的数据。样例如下:
//根据key获取
var item = ConfigTable.Get<Jyx2Item>(r1.Armor);
...
//遍历
foreach(var role in ConfigTable.GetAll<Jyx2.Jyx2Role>())
{
...
}