在游戏开发中,必定会有数据编辑、保存和读取。需要兼顾开发效率、运行效率和兼容性

数据的显示、编辑

unity的内置序列化还是比较好用的,所见即所得,但有个比较蛋疼的地方,不支持接口、多态对象。在设计数据结构的时候,如果没有多态,将会有很多数据冗余。。。

在unity2020版本中,多了一个SerializeReference特性,可以帮助我们显示多态数据,但也有个比较蛋疼的地方,它只能显示,不能编辑,你说艹蛋不艹蛋🙄,做功能只做一半之unity。

这里,我们使用Odin插件。如果没有Odin,可以考虑UnitySerializedReferenceUI。有了上面的基础,就可以在编辑器下快速创建、删除多态对象了!

不使用多态

public class data
{
    // event id
    public uint id;

    // animation event parameter
    public string animationName;

    // sound event parameter
    public string soundName;

    // more and more...
}

public class table
{
    public List<data> datas;
}

动画事件只会用到animationName,声音事件只会用到soundName,但每个data都包含了其他无用字段,这真是太。。。

如果在unityeditor下编辑,还得根据事件类型做switch case,只在面板中只曝露出有用的参数。。。不然。。。

如果采用json、xml之类自动化的方式来保存,那无用的参数就全进文本了。。。手写parser?那慢慢写吧。。。

使用多态

public abstract class data
{
    // event id
    public uint id;
}

public class animation_data : data
{
    // animation event parameter
    public string animationName;
}

public class sound_data : data
{
    // sound event parameter
    public string soundName;
}

// more and more...

public class table
{
    public List<data> datas;
}

这样数据结构看起来就清晰多了,而且不会存储不必要的东西!文件大小、内存大小都会降低!也不用编写又臭又长的编辑器代码和序列化代码!

数据的读写

处理了显示、编辑的问题,另一个问题就是编辑器读取,以及运行时读写的问题了,不过一般运行时只考虑读。

序列化库可以先选用 json.net 或者 protobuf.net,都支持多态序列化。

数据的读写有个问题,我们可能在开发过程中修改数据结构,可能有以下几种问题:

  1. 字段名改变
  2. 基元类型改变,如,int->string
  3. 容器类型改变,如,list->dictionary
  4. 数据结构类改版,如,classA包含a、b、c,现要改为classA包含classB,classB包含a、b、c

出现上述问题后,plan A,手动检查,重新弄。策划:头伸过来,我给你加个buff。哈哈哈~

plan B,使用序列化库解决:

  1. 字段名改变
    protobuf使用int作为key,仅改变字段名,没有任何影响。
    json.net则使用JsonProperty即可指定名称,类似unity的SerializeAs。
  2. 剩下所有,可以考虑如下方案
    (ProtoAfterDeserializaton、ProtoBeforeDeserializaton)、(OnSerializing、OnDeserialized)等特性标记的方法可以在对应时机的被反射调用,所以利用这个,我们可以编写兼容代码,来最大化保证数据的兼容性!

坑点

Q: SerializeReference 在类名修改后,可能会出现报错,且编辑器下ScriptableObject无法保存。

A1: 由于我们是序列化成自己的数据文件了,则可以删掉后,再重新生成ScriptableObject。

A2: 添加 [MovedFrom(false, “OldNameSpaceName”, “OldAssemblyName”, “OldClassName”)] 特性也可以解决。

结论

有了以上基础,即可在unity里编辑逻辑数据,从了避免在excel里抽象数据结构了。