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

Unity中如何读取多份ItemSettings数据并重建子GameObject状态?

问题解决:多ItemSettings序列化/反序列化与优化方案

一、循环读取多个序列化的ItemSettings

你当前的保存逻辑是逐个将ItemSettings序列化到文件,读取时需要循环调用Deserialize直到文件流到达末尾。修改读取代码如下:

public void LoadFile()
{
    string destination = "D:/Unity/test.txt";
    if (!File.Exists(destination))
    {
        Debug.LogError("File not found");
        return;
    }

    using (FileStream file = File.OpenRead(destination))
    {
        BinaryFormatter bf = new BinaryFormatter();
        List<ItemSettings> allSettings = new List<ItemSettings>();
        
        try
        {
            // 循环反序列化直到文件流结束
            while (file.Position < file.Length)
            {
                ItemSettings data = (ItemSettings)bf.Deserialize(file);
                allSettings.Add(data);
            }
        }
        catch (EndOfStreamException)
        {
            // 正常到达文件末尾,无需额外处理
        }
        catch (Exception e)
        {
            Debug.LogError($"读取失败: {e.Message}");
        }

        // 遍历所有配置重建对象
        foreach(var settings in allSettings)
        {
            // 示例逻辑:实例化预制体并设置Transform状态
            GameObject item = Instantiate(yourItemPrefab, cupboard.transform);
            item.transform.SetPositionAndRotation(settings.Position, settings.Rotation);
            item.transform.localScale = settings.Scale;
            // 其他自定义字段设置...
        }
    }
}

注意:使用using语句会自动管理文件流生命周期,比手动调用Close()更安全,能避免异常场景下的资源泄漏。

二、更优实现方案

逐个序列化存在效率低、维护复杂的问题,且Unity 2021+版本中BinaryFormatter已被标记为不安全且过时,推荐以下两种更可靠的方案:

方案1:序列化整个ItemSettings列表

将所有需要保存的ItemSettings存入一个List<ItemSettings>,一次性完成序列化/反序列化,代码更简洁且效率更高:

保存代码修改:

public void SaveProject()
{
    string path = "D:/Unity/test.txt";
    List<ItemSettings> allSettings = new List<ItemSettings>();

    foreach (Transform g in cupboard.transform)
    {
        CubeObject cubeObject = g.GetComponent<CubeObject>();
        if (cubeObject)
        {
            allSettings.Add(cubeObject.GetSettings());
        }
    }

    using (FileStream file = File.Create(path))
    {
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(file, allSettings);
    }
}

读取代码修改:

public void LoadFile()
{
    string destination = "D:/Unity/test.txt";
    if (!File.Exists(destination))
    {
        Debug.LogError("File not found");
        return;
    }

    using (FileStream file = File.OpenRead(destination))
    {
        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            List<ItemSettings> allSettings = (List<ItemSettings>)bf.Deserialize(file);
            
            foreach(var settings in allSettings)
            {
                // 重建对象逻辑
                GameObject item = Instantiate(yourItemPrefab, cupboard.transform);
                item.transform.SetPositionAndRotation(settings.Position, settings.Rotation);
                item.transform.localScale = settings.Scale;
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"读取失败: {e.Message}");
        }
    }
}

方案2:使用JsonUtility替代BinaryFormatter

Json格式可读性更强,且Unity内置的JsonUtility无安全漏洞,适合序列化简单数据结构:

确保ItemSettings可序列化:

[System.Serializable]
public class ItemSettings
{
    public Vector3 Position;
    public Quaternion Rotation;
    public Vector3 Scale;
    // 其他需要保存的自定义字段...
}

保存代码:

public void SaveProject()
{
    string path = "D:/Unity/test.json";
    List<ItemSettings> allSettings = new List<ItemSettings>();

    foreach (Transform g in cupboard.transform)
    {
        CubeObject cubeObject = g.GetComponent<CubeObject>();
        if (cubeObject)
        {
            allSettings.Add(cubeObject.GetSettings());
        }
    }

    // 用包装类解决JsonUtility无法直接序列化List的问题
    SettingsWrapper wrapper = new SettingsWrapper();
    wrapper.SettingsList = allSettings;
    string json = JsonUtility.ToJson(wrapper, prettyPrint: true);
    File.WriteAllText(path, json);
}

// 用于Json序列化的List包装类
[System.Serializable]
public class SettingsWrapper
{
    public List<ItemSettings> SettingsList;
}

读取代码:

public void LoadFile()
{
    string destination = "D:/Unity/test.json";
    if (!File.Exists(destination))
    {
        Debug.LogError("File not found");
        return;
    }

    string json = File.ReadAllText(destination);
    SettingsWrapper wrapper = JsonUtility.FromJson<SettingsWrapper>(json);
    
    foreach(var settings in wrapper.SettingsList)
    {
        GameObject item = Instantiate(yourItemPrefab, cupboard.transform);
        item.transform.SetPositionAndRotation(settings.Position, settings.Rotation);
        item.transform.localScale = settings.Scale;
    }
}

提示:若需要更小的文件体积或加密需求,可以在Json基础上添加压缩或加密逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:25:05