unity编辑器中的序列化如何理解[SerializeField]特性

之前一直对序列化和[SerializeField]特性不是很理解(若理解有误,拜请指正)

首先序列化是什么,百度如下解释

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

 

简单理解,玩游戏存档,会把存档是的玩家信息保存到一个文件中,当下次开启游戏读取存档的时候,可以继续从存档的状态开始玩

Unity编辑器也一样,public 公共属性的值 显示在属性面板中,我们可以任意修改数值(脚本中对应的数值是没有变的),关闭Unity编辑器再次打开的时候,属性的值是我们修改过的值,而不是脚本里赋的初值,说明属性的值”存档“了

存储的位置就是Unity的场景文件,用记事本打开可以查看对应的信息

首先Unity编辑器就是一款软件

当脚本中创建一个public int a = 0;的公共属性

我们就可以在属性面板(Inspector)中对a进行赋值为(例如赋值为2)

我们关闭Unity编辑器

当再次打开编辑器时a的数值为2

说明Unity编辑器已经将公共属性进行序列化(也就是记录下修改的值,类似存档)

 

[SerializeField] Attribute

强制unity去序列化一个私有域。这是一个内部的unity序列化功能,有时候我们需要Serialize一个private或者protected的属性,

using System.Collections;

using System.Collections.Generic;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

using UnityEngine;

public class Test : MonoBehaviour {

    public int a = 0;

    [SerializeField]

    int b = 0;

    void Update () {

        if (Input.GetKeyDown(KeyCode.A))

        {

            a++;

            b++;

        }

        if (Input.GetKeyDown(KeyCode.B))

        {

            Debug.LogError("a:" + a);

            Debug.LogError("b:" + b);

        }

    }

}

 

### Unity 编辑器中的序列化教程 在 Unity 中,序列化的概念主要用于保存和加载游戏对象的状态。通过序列化可以将数据存储到磁盘上或者在网络上传输,并能够在稍后的某个时间重新创建这些数据。以下是关于如何在 Unity 编辑器中实现类的序列化的详细介绍。 #### 1. 使用 `[Serializable]` 属性标记类 为了使自定义类能够被 Unity 序列化,需要为其添加 `[System.Serializable]` 或者 `[Serializable]` 属性。这使得该类可以在 Inspector 面板中显示其字段并允许编辑[^1]。 ```csharp [System.Serializable] public class MyCustomClass { public int myInt; public string myString; public MyCustomClass(int value, string text) { this.myInt = value; this.myString = text; } } ``` #### 2. 实现 `ISerializationCallbackReceiver` 接口 对于更复杂的场景,可能需要手动控制序列化过程。可以通过让类继承 `ISerializationCallbackReceiver` 并实现两个方法:`OnBeforeSerialize()` 和 `OnAfterDeserialize()` 来完成这一目标。 ```csharp using UnityEngine; [System.Serializable] public class CustomSerializedData : ISerializationCallbackReceiver { [SerializeField] private int _serializedValue; // 被实际序列化的变量 public int PublicValue { get; set; } public void OnBeforeSerialize() { _serializedValue = PublicValue * 2; // 自定义逻辑处理 } public void OnAfterDeserialize() { PublicValue = _serializedValue / 2; // 反向转换 } } ``` #### 3. 利用 `OnPhotonSerializeView` 方法(适用于 Photon 插件) 当涉及到网络同步时,可以利用 Photon 的 `OnPhotonSerializeView` 方法来管理特定的数据流传输。此函数会在每次视图更新时调用,从而允许开发者决定哪些数据应该发送给其他玩家[^2]。 ```csharp using ExitGames.Client.Photon; using Photon.Pun; public class NetworkedPlayer : MonoBehaviourPunCallbacks, IPunObservable { public float health; public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.IsWriting) { // 发送当前玩家的生命值状态 stream.SendNext(this.health); } else { // 接收其他客户端发来的生命值状态 this.health = (float)stream.ReceiveNext(); } } } ``` #### 4. 处理 C# 对象与 Native 对象之间的差异 需要注意的是,在 Unity 中存在两种类型的对象——C# 层面的对象以及原生引擎内部维护的对象。由于它们具有不同的生命周期管理和垃圾收集机制,因此可能会遇到一些意外行为[^3]。例如: - 如果尝试比较一个已被销毁的游戏物体与其对应的脚本实例,则即使后者尚未被 GC 清除,前者也可能已经变为 null。 这种情况下应谨慎判断是否真正为空指针。 --- ### 示例代码展示 下面提供了一个完整的例子演示如何在一个 MonoBehavior 类里嵌套可序列化的结构体或类,并将其暴露于 Editor GUI 上供用户调整设置[^4]: ```csharp using UnityEditor; using UnityEngine; // 定义一个简单的配置项容器 [System.Serializable] public struct ConfigItem { public bool isEnabled; public Color color; } public class ExampleEditorScriptableObject : ScriptableObject { public ConfigItem[] items; [MenuItem("Tools/Create Example Settings")] static void CreateExampleSettingsAsset() { var assetPathAndName = AssetDatabase.GenerateUniqueAssetPath("Assets/ExampleSettings.asset"); var instance = ScriptableObject.CreateInstance<ExampleEditorScriptableObject>(); instance.items = new ConfigItem[2]; instance.items[0].isEnabled = true; instance.items[0].color = Color.red; instance.items[1].isEnabled = false; instance.items[1].color = Color.blue; AssetDatabase.CreateAsset(instance, assetPathAndName); AssetDatabase.SaveAssets(); Selection.activeObject = instance; } } ``` 上述代码片段展示了如何创建带有数组属性的 ScriptableObjects ,并通过菜单命令快速生成资源文件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值