Unity序列化文件到底是如何关联MonoBehaviour的

我们知道Unity序列化文件的格式是YAML,在Inspector面板上可以拖拽的脚本、资源会被视为引用。以下YAML语句描述了一条对资源的引用:

{fileID: -1155515603, guid: 7f2f46c0507666e498f75cc4d6f91a07, type: 3}

打包后,GUID是一个32长度的string,Runtime进行处理时速度较慢,因此会被转换为int64的PathID,这一点可以才AssetStudio中解压后证实。

对于资源文件,打包时会建立一张Resource清单,包含了PathID和资源的对于关系,但是对于Mono脚本文件,这个关联机制是怎样的呢?

通过阅读AssetStudio的源码的可以发现,序列化文件引用的MonoBehaviour脚本,在打包时会被转换为序列化的MonoBehaviour类,该类持有一个PPtr<MonoScript>,而在MonoScript中则记录了类的信息:

public sealed class MonoScript : NamedObject
{
    public string m_ClassName;
    public string m_Namespace = string.Empty;
    public string m_AssemblyName;
    // ...
}

查看Unity(泄露的)源码可以发现,MonoManager提供了运行时通过这些信息获取对应类的API,并在Mono和IL2CPP下分别实现,因此我们下结论:

  1. 编辑器下,当创建一个MonoBehaviour时,Unity会分析该cs文件中同名的MonoBehaviour类(Unity要求文件名和类名一致,想必是便于分析),并维护一张cs文件GUID + FileID与类信息的关系表,无论该MonoBehaviour是在asmdef的Dll中还是直接在Assets下(在Dll中时,Dll中类的GUID为Dll的GUID,FileID则不同,都是负数)。
  2. 打包时,Unity会将关系表写入MonoScript中进行序列化,最后写入到SerializedFile中,SerializeFile随后被打入Resources或者AssetBundle。SerializeFile是Unity打包序列化YAML的格式。
  3. 运行期间,加载含有MonoBehaviour脚本时,Unity通过MonoScript包含的信息获取类信息,并对MonoBehaviour进行实例化,最后填充该MonoBehaviour实例的自定义的序列化参数,完成加载。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值