You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity编辑器模式下List元素构造函数未正确初始化字符串问题

解决Unity Inspector中List元素字符串无法从构造函数初始化的问题

我来帮你搞定这个问题——你遇到的情况其实是Unity序列化机制和常规C#构造函数执行时机不匹配导致的。虽然你的构造函数确实执行了(所以能看到"Call test"的日志),但Unity在序列化List元素的过程中,会在构造函数调用后重置那些没有序列化数据的字段,把字符串清空成默认的空值。

下面给你两种靠谱的解决方案,你可以根据需求选:

方案1:利用序列化回调接口(推荐)

通过实现ISerializationCallbackReceiver接口,在Unity完成序列化操作后再初始化字段,这样就不会被序列化系统覆盖了。

代码示例:

using UnityEngine;

[System.Serializable]
public class YourDataClass : ISerializationCallbackReceiver
{
    public string name;
    public string description;

    public YourDataClass()
    {
        Debug.Log("Call test");
        // 这里的初始化会被序列化覆盖,所以移到回调里执行
    }

    public void OnBeforeSerialize()
    {
        // 序列化前的操作,这里暂时不需要
    }

    public void OnAfterDeserialize()
    {
        // 检查字段是否为空,为空则设置占位文本
        if (string.IsNullOrEmpty(name))
        {
            name = "默认名称";
        }
        if (string.IsNullOrEmpty(description))
        {
            description = "默认描述文本";
        }
    }
}

// 挂载在GameObject上的脚本示例
public class YourBehaviour : MonoBehaviour
{
    public List<YourDataClass> dataList;
}

这样修改后,当你在Inspector里点击List的加号添加新元素时,OnAfterDeserialize会在序列化完成后触发,自动给空的name和description设置占位文本,而且构造函数的日志也会正常输出。

方案2:自定义Editor按钮添加元素

如果你更倾向于手动控制元素的创建,可以写一个自定义Editor类,添加一个按钮来创建带默认值的List元素:

代码示例:

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

[CustomEditor(typeof(YourBehaviour))]
public class YourBehaviourEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // 先绘制默认的Inspector界面
        DrawDefaultInspector();

        YourBehaviour targetScript = (YourBehaviour)target;

        // 添加自定义按钮
        if (GUILayout.Button("添加带默认值的元素"))
        {
            YourDataClass newData = new YourDataClass();
            newData.name = "默认名称";
            newData.description = "默认描述文本";
            
            // 如果List还没初始化,先实例化
            if (targetScript.dataList == null)
            {
                targetScript.dataList = new List<YourDataClass>();
            }
            
            targetScript.dataList.Add(newData);
            EditorUtility.SetDirty(targetScript);
        }
    }
}

这种方法需要用户点击自定义按钮来添加元素,不过能完全控制初始化的过程,避免序列化机制的干扰。

为什么原来的构造函数不行?

简单来说,Unity在处理序列化的List元素时,流程是这样的:

  1. 调用构造函数创建实例
  2. 尝试从序列化数据(新元素没有历史数据)填充字段
  3. 没有序列化数据的字段会被重置为类型默认值(字符串就是空)
    所以你在构造函数里设置的字符串会被这一步覆盖,而序列化回调接口是在这之后执行的,所以能保留住初始化的值。

内容的提问来源于stack exchange,提问作者Mc Midas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:38:27