Unity之SerializeField(序列化字段)的一点理解 (2014-05-08 16:32:06)

本文详细解释了Unity中SerializeField和HideInInspector的作用及使用方法,通过不同场景的示例代码帮助读者理解如何控制变量的序列化和面板显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


       最近在学习NGUI代码时遇到SerializeField,理解得不是很透彻,所以百度了一下,有以下收获,希望能对自己和他人有所帮助。(在这里由衷感谢那位大侠的分享)
       首先,Unity会自动为Public变量做序列化,序列化的意思是说再次读取Unity时序列化的变量是有值的,不需要你再次去赋值,因为它已经被保存下来。
       然后,什么样的值会被显示在面板上呢?
答案是:已经被序列化,但是没有用[HideInInspector]标记的值。
       [HideInInspector]表示将原本显示在面板上的序列化值隐藏起来。
       [SerializeField]表示将原本不会被序列化的私有变量和保护变量变成可以被序列化的,那么它们在下次读取的值就是你上次赋值的值。


       1、如果a是公有的序列化变量。
           (1)如果你想要在面板中看到变量a,那么用:
                    public int a;
           (2)如果你不想在面板中看到变量a,那么用:
                    [HideInInspector]
                    public int a;
                    这样a可以在程序中被代码赋值,但不会在面板中看到,也不能手动设置赋值。

       2、如果a是私有的序列化变量,你想在面板中读取并赋值,那么用:
             [SerializeField]
             private int a;

       3、如果a是私有的序列化变量,你想在面板中读取,但是不赋值,那么用:
            [HideInInspector][SerializedField]
            private int a;
            public int b
            {
                get{return a;}
            }
            然后在Editor中显示,EditorGUILayout.LabelField("value", game.b.ToString());

       4、如果a是私有序列化变量,你不想在面板中做任何操作(不想看到,也不想写),但是想要在程序中给它赋值,那么用。
            [HideInInspector][SerializedField]
            private int a;
            public int b
            {
                get{return a;}
                set{a = value;}
            }
来自 新浪博客 鱼的老大 

### Unity序列化字段的方法和属性 在 Unity 中,为了使类或结构体中的字段能够被编辑器识别并保存至场景或预制件中,需标记这些字段为 `public` 或者使用 `[SerializeField]` 属性将其设为可序列化的私有成员[^3]。 #### 使用 `[System.Serializable]` 和 `[SerializeField]` 当定义自定义的数据容器(如 C# 类或结构),应在其上应用 `[System.Serializable]` 特性以指示该类型可以参与序列化进程。对于那些不希望公开访问但仍需通过 Inspector 编辑的字段,则可以在其声明之前加上 `[SerializeField]` 属性: ```csharp using UnityEngine; [System.Serializable] public class PlayerData { public string playerName; [SerializeField] private int healthPoints; // ... other fields and methods ... } ``` 此代码片段展示了如何创建一个名为 `PlayerData` 的可序列化类,并包含两个字段:一个是公共字符串类型的玩家名称;另一个是带有 `[SerializeField]` 标记的整数型生命值,在默认情况下它不会显示于 Inspector 中除非显式指定允许这样做[^1]。 #### 处理特殊情形下的序列化问题 需要注意的是,某些特定条件下可能会遇到序列化异常情况,比如处理含有 null 值的对象时可能导致无限递归从而影响性能。为了避免此类问题的发生,开发者应当谨慎对待可能为空引用的情况,并考虑采用合适的策略来规避风险,例如手动控制对象生命周期或是利用条件判断防止不必要的实例化操作[^2]。 #### 自定义序列化行为 除了基本的字段序列化外,还可以重写 MonoBehaviour 组件里的虚函数 `OnBeforeSerialize()` 和 `OnAfterDeserialize()`, 这样便能在每次执行相应动作前后加入额外逻辑,确保数据的一致性和完整性[^4]: ```csharp using UnityEngine; public class CustomSerializableComponent : MonoBehaviour { void OnBeforeSerialize(){ // 执行一些预处理工作... } void OnAfterDeserialize(){ // 反序列化完成后做一些恢复设置... } } ``` 上述例子说明了怎样扩展 MonoBehviour 来实现更复杂的序列化需求,而不仅仅是简单的字段映射关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值