C# Unity游戏开发——Excel中的数据是如何到游戏中的 (四)2018.4.3更新

 本帖是延续的:C# Unity游戏开发——Excel中的数据是如何到游戏中的 (三)html

 

前言前端

 

最近项目不算太忙,终于有时间更新博客了。关于数据处理这个主题前面的(一)(二)(三)基本上算是一个完整的静态数据处理方案了。java

不过前几篇发布的时候是2015年,比较早了,随着这几年技术不断积累和进步,其实已经有更好的方案来处理数据了,不过对于前端存储的那几个M的数据,多点少点其实影响也不大。git

可是也不能就这样算了,毕竟技术的变化突飞猛进,仍是要保持持续学习的心态。github

 

虽然简单但却不易忽视数据结构

 

对于游戏中静态数据的处理,单纯的对于整个程序项目来讲其实只是很小的一部分。写个读写工具,打个包,压个缩,加个密其实对于很工具

多程序来讲也不是难事。可是,我又要说可是了。可是,根据博主的我的经验来讲,数据对于游戏的业务逻辑是很是底层的“逻辑”,对于学习

后期的开发起到了一个基础的做用。主要体如今两个方面:测试

1.业务逻辑角度的数据结构化。google

  这点很关键,策划想要把本身大脑里的游戏玩法用数据表示出来,而这个表示过程实际上是须要程序配合的,由于不可能每一个策划

  都那么牛逼,然而现实状况也确实如此。所以,这部分要作的事就是,用数据抽象的思惟把策划描述的游戏世界表示出来,最终

  体现就是“表格”。这些数据,其实就是游戏业务逻辑的“骨架”,后续的开发都是围绕着数据来作的,或者说被数据“支配”的。

2.程序结构的设计。

  第一条说过了,“后续的开发都是围绕着数据来作的”,那么这些数据的使用频率必然会很高。那么,问题来了,如何设计这部分的程序结构会使开发效率和运行效率最优?单纯的建立一个类,把全部数据查询的方法都放里面?仍是根据第一条抽象出来的“实体类”来组织数据,而后对数据作一些预处理,例如游戏运行先进行分类而后放到内存中等待使用?

  显然,后者更加高效,这也“静态数据处理虽然简单,可是也不容忽视”的理由。

 

最新的方案

  

 前面也说了,技术是不断在变化的,咱们也须要快速适应。以前的方案确实用了很长时间,也没什么问题。可是本身撸的代码总有几个疑问?这是最好的方案吗?和最好的方案差距有多大?

带着这几个问题,在最近2年所作的项目中也对这方面作了一些工做:1,在最近的项目中使用了ScriptableObject的方式。2,开始了一个protobuf方式处理数据的开源项目。

提及来惭愧,其实结果影响并不算很大,下面把这部分总结一下。

 

方案一 : 使用Unity的ScriptableObject。

 

  作法就是每一个表格生成的数据类都直接或者间接的继承自ScriptableObject类,打包的时候直接把全部表数据都生成一个对应类型的.asset文件。而后建一个总的Map类来存放全部asset的引用,固然这个Map类也必须继承自ScriptableObject,也生成对应的.asset文件。最终打包的时候,只打这个Map类的.asset文件,Unity会自动识别里面的依赖关系,将全部数据打包进bundle。

实体类Hero

using UnityEngine;
public class Hero : ScriptableObject
{
    public string name;
    public string level;
}

 

Map类

using UnityEngine;
using System.Collections.Generic;
public class Map : ScriptableObject
{
    public List<Hero> heroList = new List<Hero>();
}

 

最终在使用的时候也很方便:

                AssetBundle bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/constance");
                Map m_Constance = bundle.LoadAsset("constance") as Map;

 

这种方式对Unity3D很是友好,使用起来也很是方便,可是缺点也是有的,下面来总结一下:

优势:

  能够和预制产生依赖,prefab若是依赖了asset打包的时候也会打进去,减小了查找操做。

  能够直接用Unity API操做asset。省去了一部分序列化反序列化代码。

  能够直接用AssetBundle.LoadAsset() as Map;加载,省去了以前的反序列化代码。

  在Unty中选中asset能够直接在Inpector中看到数据。

缺点:

  生成asset的时候会有大量的文件操做,速度慢。

 

还有两个指标就是运行速度和存储空间。因为影响不大,没有作进一步测试。

存储空间的话,我这里有个参考:6个Excel文件占用的pc上的磁盘空间是112k,最终打成AssetBundle是31k。

 

 方案二 : 使用protobuf

   

  这种作法主要是经过google提供的protobuf来序列化和反序列化数据,而且使用protoc生成目标语言的代码。工做流程以下图所示。

 

 

   把作法分红几部分来讲:

    操做1,读取excel数据描述信息,经过excel数据描述信息生成.proto文件。

    操做2,使用protoc命令行生成本地代码,也就是你制做工具使用的语言代码。

    操做3,建立本地代码的类的实例。

    操做4,读取excel数据,而且将内容赋值给“操做3”建立的实例,最终使用protobuf API序列化。

    操做5,生成目标平台的代码。

  最终生成的二进制文件(.bytes)和目标代码会和程序一同发布,使用生成的目标代码解析生成的二进制数据。

  具体代码就不贴出了,下面是本人对方案二开启的一个开源项目,用的是java+netbean8.2,目前已经完成大部份内容。

  有兴趣的同窗能够看一下。我会一直更新。

  https://github.com/superbig/proto-packer

 

最后

 

  若是你在游戏开发的静态数据处理方面还在犹豫,建议是:若是项目小但是试试ScriptableObject方式,应使用起来确实要方便一些。固然你也须要忍受数据导出时候的频繁的IO操做(固然其实你也能够开发一个增量导出的工具)。

若是项目大,数据不少仍是老老实实用protobuf,空间占用少,速度快。或者本身写。

相关文章
相关标签/搜索