Skip to content

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类实例

概念补充说明

绑定关系详细说明

  • 每一个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>())
{
    ...
}