据我所知unity Serialization对于基本数据类型非常好用,但处理复类型时就有些基础缺陷了。
我的需求是连接组件和文件并永久保存这种关系。而组件(或游戏对象)的InstanceID不管用,因为每次场景加载都会不一样。
Unity内置的持久化策略是通过“m_LocalIdentfierInFile”(将检视面板视图切换为Debug模式即可看到该字段)来连接场景文件和游戏对象及其组件的(这个肯定是Unity的拼写错误,应该是Identifier,当然它也没有要改正的倾向)。
所以我也可以利用这个字段来做些什么啊。但最大的难题是UnityEngine没有提供任何可以使用该字段的接口,也没说明要如何用,几番查证得知这是在引擎的C++端实现的。
废话少说,多方尝试之后最后想出了一个简单的解决办法,就是在编辑器中复制一份“m_LocalIdentfierInFile”,并将其保存为序列化的属性。
但是,它对于运行时创建的游戏对象或组件并不管用。
下面是实现方法 :
- // This is a copy of the "m_localIndentiferInFile"
- // (don't forget to use [Serializable] on the class)
- [SerializeField]
- private int persistentID = -1;
结合下面这段代码就可以访问“m_LocalIdentfierInFile”了,确保该段代码添加了编辑器预定义宏(#ifdef UNITY_EDITOR),并且不要引用UnityEditor命名空间,否则会导致编译失败。
- // Init this instance, it's public so it can be called from a InspectorScript
- // is only set via the unity editor
- public void init ()
- {
- #if UNITY_EDITOR
- PropertyInfo inspectorModeInfo =
- typeof(UnityEditor.SerializedObject).GetProperty ("inspectorMode",
- BindingFlags.NonPublic | BindingFlags.Instance);
- UnityEditor.SerializedObject serializedObject =
- new UnityEditor.SerializedObject (comp);
- inspectorModeInfo.SetValue (serializedObject, UnityEditor.InspectorMode.Debug, null);
- UnityEditor.SerializedProperty localIdProp =
- serializedObject.FindProperty ("m_LocalIdentfierInFile")
- //Debug.Log ("found property: " + localIdProp.intValue);
- persistentID = localIdProp.intValue;
- //Important set the component to dirty so it won't be overriden from a prefab!
- UnityEditor.EditorUtility.SetDirty (this);
- #endif
- }
上面的脚本最初由thelackey3326发布在Unity论坛中,最后加上一句“UnityEditor.EditorUtility.SetDirty (this);”,以防预制件persistentID被重写。
下面是在OnEnable()中调用init()方法:
- public void OnEnable ()
- {
- myPersist.init ();
- }
这只在场景保存后有用(保存之前m_LocalIdentfierInFile == 0),在创建了游戏对象或拖拽预制件之后保存场景且至少点击一次游戏对象!
通常如果将预制件拖拽到场景中,就表示点击了它并进行了一些操作。
在场景即将保存时可以访问其中一些数据,Unity没有提供保存场景后进行访问的方法。下面的代码是在保存场景前调用init()函数:
完整源码点此链接。
以上代码表示,如果创建一个游戏对象,并使用编辑器获取“m_LocalIdentfierInFile”字段,就必须在此之后至少保存两次场景。第一次是让Unity设置“m_LocalIdentfierInFile”,第二次是将其保存到局部变量中。这并非最便捷的方法,但也够用了,只需使用持久化的游戏对象设置下场景就好。
相关推荐
unity序列化工作原理和实例.docx unity序列化工作原理和实例.docx unity序列化工作原理和实例.docx unity序列化工作原理和实例.docx unity序列化工作原理和实例.docx
Unity 中使用Protobuf进行序列化和反序列化的Demo
Unity序列化和反序列XML并添加属性2
该代码为Unity Editor 使用序列化保存数据,将数据显示在Inspector 面板上的操作
简单快捷的序列化存储。
unity字典序列化工具SerializableDictionary 仅供学习,请勿商用。
Unity最快的序列化/反序列化工具
Unity序列化插件 ODin
在unity用于json的序列化和反序列化插件(适用语言c#) 配合教程参见我的“unity/c#解析json”
unity2018的 Json 文件的序列化反序列化读写工程,主要是支持反序列化读取Json文件,序列化写入Json文件的unity2018的Demo。里面自带了Newtonsoft.Json的Newtonsoft.Json.dll。
如果只想获取当前画面的一帧,就点击截取当前画面就行了,如果要导出动画的序列帧,勾选启用导出序列帧,设置起始到结束帧即可
简单实现unity序列帧,为这段时间的项目小demo之一,这些技术最后均使用到实际工程项目中。现在开始总结博客与demo,留作将来再次需要时使用。
在Unity5中Protobuf的序列化和反序列化,解决了因Android和IOS平台的不同而不能解析的问题。
主要为大家详细介绍了Unity代码实现序列帧动画播放器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
[ProtoContract] //声明这个类能被序列化 public class UserData { //声明每一个需要被序列化的成员,编号从1开始 [ProtoMember(1)] public int id; [ProtoMember(2)] public string name; [ProtoMember...
数据持久化从某种意义上来说,就是序列化和反序列化化的过程。在.NET中我们可以将对象序列化为Xml、Json、二进制。然后通过反序列化重新获得对象。同样,在Android中我们可以通过使用Preferences来存储键值型数
Unity的可序列化字典类。 Unity无法序列化标准字典。 这意味着它们将不会在检查器中显示或编辑,并且不会在启动时实例化。 一个经典的解决方法是将键和值存储在单独的数组中,并在启动时构造字典。 该项目提供了一...
unity 移动端持久化保存数据demo,有一个简单的数据加密功能, 在demo场景里有个案例
unity自带的帧动画机很方便,我们首先选择所要播放序列帧动画的Image,然后在Window下选择Animation,会弹出一个动画制动的界面,我们选择Create,然后进入如下界面: 我们按照如下添加动画控制的属性, 然后将...
Unity5Google Protobuf解析工具,支持android/ios泛型列表参数正反序列化,下载即可用