这两天在看FairyGUI的工作流程,在加载FairyGUI某个组件的时候需要先AddPackage,然后在CreateObject,这时才能正确加载组件。

要了解FairyGUI加载包生成UI的过程,要先了解FairyGUI编辑器生成包的格式。在FairyGUI编辑器里面发布包之后会生成三个重要的文件,一个是.bytes文件,一个是.png文件,一个是*.sprites.bytes文件。这三个文件也是需要拷贝到Unity的三个文件,第一个文件是描述包结构的文件,第二个是atlas文件,第三个是描述atlas的文件。FariyGUI主要是依靠解析第一个文件来生成基本的UI。打开该文件能看到一些是一些标记与标签的集合。乍一看以为是XML文件,其实不是,是类似XML的文件,FairyGUI自己实现了一个字符串解析工具来解析该文件的内容。大概可以分为以下几个步骤:

1.UIPackage.AddPackage方法会先找到对应的包名,找到packageDescription标签,并且找到该标签节点下面的resource列表,然后根据resource列表进行逐个加载,加载atlas,image,component等,这里要注意的是FairyGUI会把resource列表里的所有image全部加载,component只加载component data.

2.UIPackage.CreateObject会通过参数提供的包名和资源名去实例化对象。具体过程是这样的:

  • 在resource列表里面找到资源名匹配的名字,如果资源是image则直接实例化出来,如果不是则进行下一步。
  • 找到刚刚匹配名字对应的id,通过id找到对应的xml配置,初始化控制器,初始化displayList里面的element.最终每个资源都会在resource里面找到,否则会出现某element加载不出来的问题。需要注意的是,在resource里面找资源名的时候,如果是component的话,则需要获取到id,通过id找到对应的xml配置,然后在遍历displayList里面的元素的时候,找的是src,通过src找到最终的资源。然后根据其他配置信息初始化位置信息,大小信息等。

在实例化的过程中涉及到FairyGUI的基础组件构造,简单画了一个UML图方便理解各个基础组件之间的关系,如下图:

如图可以看出GObject是所有组件的基类,它定义了组件的组件的基础信息,比如位置,缩放等,继承于它的组件各自实现自身特有的功能。GRoot是生成的资源的父节点,用来管理生成的所有的资源的整体行为,它站在资源的上层。

上面这个图有一个很重要的点没有说,比如组件GImage引用了Image, 而Image引用了NGraphics,NGraphics生成了网格和自动添加了Material,这样组件就显示出来了。