• GameFrameWork框架(Unity3D)使用笔记(六)游戏主流程ProcedureMain——从数据表加载出所需实体


    目录

    前言: 

    一、Entity配置表

    1、创建数据表

     2、创建数据表行类

     二、Character配置表

    1、创建数据表

     2、写数据表行类

    三、加载数据表

    四、扩展一下Entity模块

    五、应用Character数据表的位置信息

    六、测试

    总结:


    前言: 

            上一篇中我们已经成功在场景中加载出了玩家实体,并且能够控制玩家移动。但是上次是直接调用实体模块加载出实体,在游戏体量大了之后,代码中到处充斥着这种加载方式的代码就会带来诸多问题,比如需要改变实体的资源路径名的话,就得找到各处的相关代码进行修改,这将大大提高维护和修改复杂度。所以我们需要引入数据表这样一个伟大的东西,来对游戏主体和实体资源之间进行进一步的解耦。

            这一次我们将借用数据表,先配置实体数据表的信息,然后读取数据表的配置信息加载出实体。


    一、Entity配置表

    1、创建数据表

    首先在excel里面这么打:

    (#开头的是注释。要真正搞懂数据表怎么写与其看各种教程比较推荐啃源码,看看源码是怎么处理读取的数据表的字符串的,这样自己可以不用总是按照StarForce的格式写,也可以自定义自己的数据表格式,自定义解析数据表的方式等。)

    接着导出为txt文件Entity,放到数据表文件夹下面:

     2、创建数据表行类

    数据表行类的作用就是用来解析数据表的每一行的,看看StarForce的就知道怎么写了:

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.IO;
    5. using System.Text;
    6. using UnityGameFramework.Runtime;
    7. namespace ShadowU
    8. {
    9. public class DREntity : DataRowBase
    10. {
    11. private int m_Id;
    12. public override int Id
    13. {
    14. get { return m_Id; }
    15. }
    16. public string AssetName
    17. {
    18. get;
    19. private set;
    20. }
    21. public override bool ParseDataRow(string dataRowString, object userData)
    22. {
    23. string[] columnStrings = dataRowString.Split(DataTableExtension.DataSplitSeparators);
    24. for (int i = 0; i < columnStrings.Length; i++)
    25. {
    26. columnStrings[i] = columnStrings[i].Trim(DataTableExtension.DataTrimSeparators);
    27. Log.Debug(columnStrings[i]);
    28. Log.Debug(columnStrings[i].Length);
    29. }
    30. int index = 0;
    31. index++;
    32. m_Id = int.Parse(columnStrings[index++]);
    33. AssetName = columnStrings[index++];
    34. return true;
    35. }
    36. public override bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData)
    37. {
    38. using (MemoryStream memoryStream = new MemoryStream(dataRowBytes, startIndex, length, false))
    39. {
    40. using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8))
    41. {
    42. m_Id = binaryReader.Read7BitEncodedInt32();
    43. AssetName = binaryReader.ReadString();
    44. }
    45. }
    46. return true;
    47. }
    48. }
    49. }

     二、Character配置表

    这个表用来配置和角色相关的信息,暂时就配置一个角色的初始位置.(以后多关卡可以扩展)

    1、创建数据表

     

     2、写数据表行类

     

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.IO;
    5. using System.Text;
    6. using UnityGameFramework.Runtime;
    7. namespace ShadowU
    8. {
    9. public class DRCharacter : DataRowBase
    10. {
    11. private int m_Id;
    12. public override int Id
    13. {
    14. get { return m_Id; }
    15. }
    16. public Vector3 SpawnPosition
    17. {
    18. get;
    19. private set;
    20. }
    21. public override bool ParseDataRow(string dataRowString, object userData)
    22. {
    23. string[] columnStrings = dataRowString.Split(DataTableExtension.DataSplitSeparators);
    24. for (int i = 0; i < columnStrings.Length; i++)
    25. {
    26. columnStrings[i] = columnStrings[i].Trim(DataTableExtension.DataTrimSeparators);
    27. Log.Debug(columnStrings[i]);
    28. Log.Debug(columnStrings[i].Length);
    29. }
    30. int index = 0;
    31. index++;
    32. m_Id = int.Parse(columnStrings[index++]);
    33. index++;
    34. string[] rowSpawnPosition = columnStrings[index++].Split('|');
    35. SpawnPosition = new Vector3(int.Parse(rowSpawnPosition[0]),int.Parse(rowSpawnPosition[1]), int.Parse(rowSpawnPosition[2]));
    36. return true;
    37. }
    38. //还有个解析二进制数据的没必要写因为我不是二进制数据存储的
    39. }
    40. }

    三、加载数据表

    数据表都搞好了,下面就是加载数据表以备试用。

    在ProcedureLaunch流程里面加载数据表的逻辑里面加载我们新增的两个表:

     就这么简单。


    四、扩展一下Entity模块

     咱把”加载主角实体“这个操作整合到一个函数ShowPlayer()里面,并且作为Entity模块的一个扩展方法:


    五、应用Character数据表的位置信息

    数据表里的这个SpawnPosition位置信息,是要写到玩家实体对应的PlayerData类的实例数据里的Position属性里去的,最终Entity模块会根据实体数据里的Position属性确定生成实体的位置。

    所以我们在PlayerData的构造方法里面查询数据表,填上玩家出生的位置信息:


    六、测试

    现在我们整个读取数据表加载实体的流程基本上搞定了。

    我们已经创建了数据表信息,数据表行类,并且在游戏初始化的时候加载数据表。

    我们利用Character数据表里的出生位置信息赋予玩家实体初始位置。

    我们利用用Entity数据表里的资源名称信息加载玩家实体资源。

    下面我们在主流程中调用我们写的扩展方法ShowPlayer()看看效果:

     但是报错了:

    找了半天错误我真的没话讲。。。

    原因是数据表最后有两行空行。。。。删掉就好了。

    然后在解决这个bug的时候我还发现自己代码的一些错误,DRCharacter里解析坐标时候的Int.Parse()要改成float.Parse():

    然后重新运行:

    点击开始

    哦看来是没问题了,就是初始坐标设置的有问题(红色报错是个人问题不用管)

     数据表改个坐标:

    再次运行:

    成功!


    总结:

    养成实体从数据表配置中加载的好习惯。

     

     

     

  • 相关阅读:
    MCU平台使用SPI-DirectC实现FPGA在线升级
    JAVA数据类型及自动类型转换、强制类型转换
    chrome中的一些调试工具
    【C++】set / multiset容器
    Linux - 进程概念
    简单介绍一下 git reflog
    【Linux开发基础知识】Makefile语法
    【Gazebo入门教程】第一讲 Gazebo的安装、UI界面、SDF文件介绍
    新美域杂志新美域杂志社新美域编辑部2022年第6期目录
    SpringBoot+Vue项目智能选课系统
  • 原文地址:https://blog.csdn.net/HowToPause/article/details/127882815