Unity3D研究院编辑器之[System.Serializable]数组List对象添加默认值(二十七)

本文介绍了一种在Unity中为序列化数组或列表设置默认值的方法,以解决因默认值导致的游戏模型显示问题。

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

本文固定链接: http://www.xuanyusong.com/archives/4371
雨松MOMO 2017年04月19日 于 雨松MOMO程序研究院 发表

[System.Serializable]对象放在数组中,默认在Inspector面板上Array的数量是0,如果在这里修改数量,新加的元素在Inspector面板上它是没有默认值的。

比如:我有一个很轻量级的控件,代码中需要序列化List数据,没必要在写个类OnInspectorGUI中自定义绘制它。使用者会在Inspector面板中决定序列化的数量,可是使用者并不知道要填写什么样的值进去, 如果int都是默认值是0 bool默认值是false 可能下面就会有问题。

再具体举个例子,比如我需要序列化一个模型的缩放scale系数,int 的默认值是0。使用者第一个添加了元素(他并不知道这里需要填1)放到游戏里模型就不显示了,因为scale是0 坑吧~

今天我无意间发现一个方法也算半完美解决了这个问题。如下代码所示,声明Array或者List的时候强制设置添加一个元素进去。(代码很简洁)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour 
{
    public Data[] data1= new Data[1];
    public List<Data> data2 = new List<Data> (){ new Data () };
}


[System.Serializable]
public class Data
{
    public int  a =500;
    public bool b = true;
    public Data1 subData;
}

[System.Serializable]
public class Data1
{
    public int  c = 300;
    public bool d = false;
}

如下图所示,当把脚本挂在gameObject上的时候,第一个元素对象就自动加上了默认值。
这里写图片描述
如下代码所示,如果按照老的方式来做,不去默认添加一个新元素。

public class Test : MonoBehaviour 
{
    public Data[] data1;
    public List<Data> data2;
}

如下图所示,修改了List数量后[System.Serializable] 在Inspector面板上就不会出现默认值了。。
这里写图片描述
最后,上面我说过这个方法只是半完美。原因就是在Inspector面板上修改Array的数量的时候,Unity会自动把元素的值copy给新的元素。所以说如果数量变化,新的元素的默认值会是上一个元素的值。(我觉得这也不影响,因为使用者更关心第一次输入的默认值是否正确)

转by:蒋志杰

### Unity 中 `[System.Serializable]` 的作用 在 Unity 开发中,`[System.Serializable]` 是一种属性标记,用于指示某个类或结构体可以被序列化。这意味着该类型的实例可以在特定场景下转换为字节流并存储到文件或其他介质中,或者通过网络传输后再恢复成原始状态。 #### 序列化的定义 序列化是指将对象的状态信息转化为可存储或传输的形式的过程[^1]。对于 Unity 而言,这通常意味着允许开发者更方便地操作自定义数据类型,并将其集成到 Unity 编辑器的工作流程中。 --- ### `[System.Serializable]` 的主要功能 以下是 `[System.Serializable]` 在 Unity 中的主要用途: #### 1. **支持可视化编辑** 当一个类被标记为 `[System.Serializable]` 后,其字段会暴露给 Unity 编辑器,从而使得这些字段可以直接在 Inspector 面板中进行修改和配置[^2]。这种特性极大地简化了开发过程,因为无需额外编写代码即可调整参数。 #### 2. **实现持久化存储** 通过 `[System.Serializable]` 标记的类能够参与序列化/反序列化过程,因此它们的数据可以轻松保存至磁盘(例如 JSON 文件、二进制文件等)并在稍后加载回来。这对于存档机制尤其重要。 #### 3. **增强灵活性** 即使某些类未继承 `MonoBehaviour` 或其他特殊基类,只要加上此标签就可以让其实例成为可序列化的实体[^3]。这样就扩展了哪些类型能参与到 Unity 的核心工作流之中。 --- ### 示例代码解析 下面是一个典型的例子来展示如何应用 `[System.Serializable]`: ```csharp using UnityEngine; public class SerializableExample : MonoBehaviour { public Test test; void Start() { Debug.Log($"ID: {test.id}, Name: {test.name}, Vector3: {test.vector3}"); } } [System.Serializable] public class Test { public int id = 100; // 默认整数值 public string name = "xpw"; // 默认字符串值 public Vector3 vector3; // 可视化向量变量 } ``` 在这个案例里,我们创建了一个名为 `Test` 的类,并为其添加了 `[System.Serializable]` 属性。之后,在另一个挂载于 GameObject 上的脚本 (`SerializableExample`) 中声明了一个公开成员变量 `test` 类型为刚才定义好的 `Test` 。由于有了前面提到的那个标志符存在,所以现在这个新加入的对象也能够在 Scene Hierarchy 下面对应的组件面板里面看到各个子项的具体设置界面^。 另外值得注意的是如果我们在程序执行期间动态分配内存空间给此类别的任何个体,则无论是在哪里完成初始化动作都不会影响最终呈现出来的外观表现形式[^4]^。 --- ### 总结 综上所述,`[System.Serializable]` 不仅提供了强大的工具帮助程序员更好地管理复杂项目内的各种资源关系网路图谱;而且还能有效减少重复劳动次数提高工作效率的同时保持良好的用户体验质量标准不变! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值