本文分享一个用于分析MonoBehaviour上序列化数据字段信息的工具
在使用Unity开发中,我们有时需要分析挂在Prefab上脚本的序列化数据格式,比如:
做增量式的Asset Bundle打包时,就需要判断序列化数据是否与前一个版本相同,如果Bundle和脚本上的序列化字段不一致,则加载资源时Unity就会报出一个序列化字段不匹配的错误,导致加载失败
The AssetBundle could not be loaded because it references scripts that are not compatible with the currently loaded ones. Rebuild the AssetBundle to fix this error.
WWW download had an error:The AssetBundle could not be loaded because it references scripts that are not compatible with the currently loaded ones. Rebuild the AssetBundle to fix this error.AssetBundle loading failed because the MyMonoScript class serialization hash does not match. Supported: 2a66b79b, loading: 5ab6257e AssetBundleloading failed because the MyMonoScript class serialization hash does not match. Supported: e262cf75, loading: 92d7bacd
如果你嫌弃Unity的资源加载速度,你可以由此实现一个Prefab上脚本序列化代码生成器
例如在NGUI中,一个UISprite上序列化数据如下:
在Unity中,有如下字段会被序列化:
- 所有没有标记有NonSerialized属性的public字段
- 所有标记有SerializeField属性的字段
- 支持的类型除了所有基础类型之外,还有数组,List<>,和标记有Serializable的class和struct
下面是主要的分析代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;
using CSharpExtensions;
namespace CSharpExtensions {
public static class TypeExtensions {
public static string ToGenericTypeString( this Type t ) {
if ( !t.IsGenericType )
return t.Name;
string genericTypeName = t.GetGenericTypeDefinition().Name;
genericTypeName = genericTypeName.Substring( 0,
genericTypeName.IndexOf( '`' ) );
string genericArgs = string.Join( ",",
t.GetGenericArguments()
.Select( ta => ToGenericTypeString( ta ) ).ToArray() );
return genericTypeName + "<" + genericArgs + ">";
}
}
}
public static class MonoScriptDumper {
static Type[] BaseTypes = {
typeof(