`
clm__
  • 浏览: 6499 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Unity序列化和持久化

阅读更多
据我所知unity Serialization对于基本数据类型非常好用,但处理复类型时就有些基础缺陷了。
 
我的需求是连接组件和文件并永久保存这种关系。而组件(或游戏对象)的InstanceID不管用,因为每次场景加载都会不一样。
 
Unity内置的持久化策略是通过“m_LocalIdentfierInFile”(将检视面板视图切换为Debug模式即可看到该字段)来连接场景文件和游戏对象及其组件的(这个肯定是Unity的拼写错误,应该是Identifier,当然它也没有要改正的倾向)。
 
所以我也可以利用这个字段来做些什么啊。但最大的难题是UnityEngine没有提供任何可以使用该字段的接口,也没说明要如何用,几番查证得知这是在引擎的C++端实现的。
 
废话少说,多方尝试之后最后想出了一个简单的解决办法,就是在编辑器中复制一份“m_LocalIdentfierInFile”,并将其保存为序列化的属性。
 
但是,它对于运行时创建的游戏对象或组件并不管用。
 
下面是实现方法  
 
  1. // This is a copy of the "m_localIndentiferInFile"
  2. // (don't forget to use [Serializable] on the class)
  3. [SerializeField]
  4. private int persistentID = -1;
复制代码
 
结合下面这段代码就可以访问“m_LocalIdentfierInFile”了,确保该段代码添加了编辑器预定义宏(#ifdef UNITY_EDITOR),并且不要引用UnityEditor命名空间,否则会导致编译失败。

 

  1. // Init this instance, it's public so it can be called from a InspectorScript
  2. // is only set via the unity editor
  3. public void init ()
  4. {
  5.     #if UNITY_EDITOR
  6.     PropertyInfo inspectorModeInfo =
  7.     typeof(UnityEditor.SerializedObject).GetProperty ("inspectorMode",
  8.     BindingFlags.NonPublic | BindingFlags.Instance);
  9.     UnityEditor.SerializedObject serializedObject = 
  10.     new UnityEditor.SerializedObject (comp);
  11.     inspectorModeInfo.SetValue (serializedObject, UnityEditor.InspectorMode.Debug, null);
  12.     UnityEditor.SerializedProperty localIdProp =
  13.     serializedObject.FindProperty ("m_LocalIdentfierInFile")  
  14.     //Debug.Log ("found property: " + localIdProp.intValue);
  15.     persistentID = localIdProp.intValue;
  16.     //Important set the component to dirty so it won't be overriden from a prefab!
  17.     UnityEditor.EditorUtility.SetDirty (this);
  18.     #endif
  19. }
复制代码
 
上面的脚本最初由thelackey3326发布在Unity论坛中,最后加上一句“UnityEditor.EditorUtility.SetDirty (this);”,以防预制件persistentID被重写。
 
下面是在OnEnable()中调用init()方法:
 
  1. public void OnEnable ()
  2. {
  3.     myPersist.init ();
  4. }
复制代码
 
这只在场景保存后有用(保存之前m_LocalIdentfierInFile == 0),在创建了游戏对象或拖拽预制件之后保存场景且至少点击一次游戏对象!
 
通常如果将预制件拖拽到场景中,就表示点击了它并进行了一些操作。
 
 
在场景即将保存时可以访问其中一些数据,Unity没有提供保存场景后进行访问的方法。下面的代码是在保存场景前调用init()函数:
 
  1. static string[] OnWillSaveAssets (string[] paths)
  2.     {
  3.         Object[] objs = Component.FindObjectsOfType (typeof(PersistObject));
  4.         //Debug.Log ("OnWillSaveAssets " + objs.Length);
  5.         foreach (Object obj in objs) {
  6.                 PersistObject persist = (PersistObject)obj;
  7.                 persist.init ();
  8.         }
  9.         return paths;
  10.     }
复制代码
 
完整源码点此链接
 
以上代码表示,如果创建一个游戏对象,并使用编辑器获取“m_LocalIdentfierInFile”字段,就必须在此之后至少保存两次场景。第一次是让Unity设置“m_LocalIdentfierInFile”,第二次是将其保存到局部变量中。这并非最便捷的方法,但也够用了,只需使用持久化的游戏对象设置下场景就好。
 
分享到:
评论

相关推荐

    unity字典序列化工具SerializableDictionary

    3. **序列化和反序列化方法**:为了配合Unity的序列化流程,`SerializableDictionary`类需要包含特殊的属性或方法,比如`[SerializeField]`标记的私有字段,以及可能的`OnBeforeSerialize()`和`OnAfterDeserialize()...

    unity序列化工作原理和实例.docx

    ### Unity序列化工作原理与实例解析 #### 一、序列化的概念 序列化是指将对象的状态信息转换为可以存储或传输的形式(如内存、数据库或文件)。这一过程主要用于存储对象以便后续使用。例如,在处理一个向量时,...

    dotnet-Unity最快的序列化反序列化工具

    在Unity游戏引擎中,开发人员经常需要处理对象的序列化和反序列化,以便于存储游戏状态、网络传输或者持久化数据。"dotnet-Unity最快的序列化反序列化工具"是一个专为提升.NET开发效率而设计的解决方案,特别是在...

    unity游戏序列化编辑器插件Odin - Inspector and Serializer v3.0.3

    在Unity中,序列化是管理游戏对象状态和数据的关键技术,而`Odin Inspector and Serializer`则是一个高效且功能丰富的第三方插件,用于增强Unity内置的序列化系统。此插件由Sirenix公司开发,版本号为v3.0.3,专为...

    Unity3D游戏开发数据持久化PlayerPrefs的用法详解

    数据持久化从某种意义上来说,就是序列化和反序列化化的过程。在.NET中我们可以将对象序列化为Xml、Json、二进制。然后通过反序列化重新获得对象。同样,在Android中我们可以通过使用Preferences来存储键值型数

    派生类的序列化Serialize

    在编程领域,序列化是一个非常重要的概念,尤其是在对象持久化、网络传输或数据存储时。在C#中,XML序列化是一种将对象的状态转换为XML文档的过程,以便于存储或传输。当我们涉及到派生类的序列化时,情况可能会变得...

    序列化和反序列化会出现“k_BackingField”

    在.NET平台中使用`DataContractJsonSerializer`进行序列化和反序列化时,可能会遇到一个名为“k_BackingField”的字段出现在生成的JSON字符串中。这通常是因为.NET框架为了支持属性更改通知等特性,在某些情况下会...

    【unity之数据持久化】制作一个数据管理类(存储排行榜信息)-PlayerPrfs

    在这个例子中,我们使用了Unity内置的`JsonUtility`来序列化和反序列化`List<int>`,因为`PlayerPrefs`只能存储字符串。这样,我们可以方便地保存和读取排行榜数据。 需要注意的是,`PlayerPrefs`并不适合存储大量...

    Unity游戏存档和读档教程.rar

    你可以编写自定义的序列化和反序列化函数,将游戏状态转化为字符串或其他形式的数据,然后写入文件或从文件读取。 例如,你可以创建一个`SaveManager`类,管理存档和读档的过程: ```csharp public class Save...

    iOS 数据持久化(二)对象归档ArchiverDemo

    归档的作用就是将对象以文件的形式保存到磁盘中,以使得数据序列化和持久化。 使用归档的时候读取该文件保存路径来读取文件的内容,归档的文件是进行过保密处理的,在磁盘上是无法查看文件的内容的,这也是和属性...

    最新Unity Odin插件

    在Unity中,编辑器和序列化系统对于开发者来说至关重要,它们直接影响到项目的开发效率和代码管理。Odin是一个第三方插件,专为Unity设计,旨在增强其内置的Inspector和序列化功能,从而提高开发者的生产力。 标题...

    Unity使用的protobuf-net

    5. **持久化数据**:还可以将protobuf-net序列化的数据保存到本地文件,实现游戏数据的持久化存储。 总之,protobuf-net为Unity开发提供了强大且高效的序列化工具,无论是在网络通信还是数据存储方面,都能带来显著...

    unity xlua 已集成json和pb

    6. **优化性能**:在处理大量数据时,注意对序列化和反序列化的性能进行优化,避免不必要的数据拷贝和转换。 通过这种集成,开发者可以在Unity项目中灵活地选择JSON或PB作为数据交换格式,根据实际需求权衡速度、...

    最强unity扩展 odin 3.0.1 最新版

    - `Sirenix.OdinInspector.Serializers`包含一系列序列化选项,用于处理不同数据类型的序列化和反序列化。 总的来说,Odin Inspector and Serializer是Unity开发者提高工作效率和代码质量的利器,特别是对于那些...

    Unity3D 游戏引擎之游戏场景的切换与持久化简单数据的储存

    总结来说,Unity3D游戏场景的切换和数据持久化是游戏开发的核心技术。理解并掌握这些技能,开发者能够创建更流畅、更丰富的游戏体验,同时确保玩家的进度得到妥善保存。在实际项目中,结合使用各种存储方法,可以...

    Unity数据存储项目源码

    Unity的SerializeField特性标记私有字段以便序列化,而Unity的内置函数如JsonUtility或第三方库如Newtonsoft.Json可用于序列化和反序列化。 3. **SQLite数据库**:对于更复杂的数据存储需求,Unity可以集成SQLite...

    一套unity换装系统,包含模型和动画

    9. **序列化和持久化**:为了让玩家保存和加载他们的装扮,需要实现序列化和持久化机制。Unity 支持内置的 serialization 或者第三方库如 Json.NET 来处理数据存储。 10. **错误处理和调试**:源码中可能包含了错误...

    unity odin 插件

    5. **序列化扩展**:Odin不仅增强了Unity的序列化系统,还支持对非Unity内置类型进行序列化,包括自定义类、枚举等,使得数据持久化更加灵活。 6. **性能优化**:考虑到游戏性能的重要性,Odin在提供丰富的功能的...

    EasySave3.unitypackage

    EasySave3的源码提供了学习Unity数据持久化和序列化的好机会。通过阅读源码,开发者可以了解如何实现序列化、反序列化,以及文件操作的底层逻辑。这有助于提升对Unity的深入理解,同时也方便进行二次开发或定制化...

    Unity 自己制作的日历小工具

    这需要掌握Unity的数据持久化技术,如PlayerPrefs、XML或JSON序列化等。 此外,为了提升用户体验,还可以考虑添加触摸屏操作的支持,以便在移动平台上使用。Unity提供了一系列的InputManager设置和EventSystem组件...

Global site tag (gtag.js) - Google Analytics