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

如何在Unity中读取JSON并转为DialogSequence对象数组?

解决Unity中Twine导出JSON的反序列化问题

核心问题拆解

你遇到的问题主要来自三个方面:

  1. DialogSequence类的定义问题:继承了MonoBehaviour的类无法被JsonUtility直接序列化/反序列化,因为这类对象是Unity的组件实例,并非普通数据类。同时Sprite是Unity引用类型,不能直接序列化为字符串,需要改用路径存储。
  2. JSON结构与C#类不匹配:你的JSON外层是包含Story数组的对象,而Story中每个元素是动态键(剧情标题)对应DialogSequence数组的结构,JsonUtility对这种动态键的支持很差。
  3. 反序列化调用错误:你直接用JsonUtility.FromJson<DialogSequence[]>解析,但JSON根节点是对象而非数组,类型完全不匹配,导致报错。

具体解决方案

1. 重构DialogSequence数据类

先把它改成普通可序列化的数据类,替换Sprite为路径字符串:

[System.Serializable]
public class DialogSequence
{
    public string TextDialog; // 对话框文本
    public string TextNameCharacter; // 显示的角色名
    public string SpriteCharacterPath; // 角色图片路径(替代原Sprite)
    public string SpriteBackgroundPath; // 背景图片路径(替代原Sprite)
    public bool ChoiceMultiple; // 是否有多选项
    public string[] TextChoice; // 按钮文本(最多4个)
    public string[] IndexChoice; // 下一场景的数组索引/键
}

后续在Unity中通过路径加载Sprite,比如用Resources.Load<Sprite>(SpriteCharacterPath),注意图片要放在Resources文件夹下,或用Addressables管理。

2. 使用Newtonsoft.Json处理动态键(推荐)

Unity自带的JsonUtility对动态键(比如每个剧情的自定义标题)支持有限,建议用Newtonsoft.Json(Unity官方适配版本,可通过Package Manager安装),它能轻松解析这种结构。

步骤:

  • 打开Unity Package Manager → 点击+ → 选择Add package from git URL → 输入com.unity.nuget.newtonsoft-json安装。

  • 解析代码示例:

using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEngine;

public class MainGame : MonoBehaviour
{
    void Start()
    {
        // 假设jsonString是你的JSON内容
        string jsonString = "...";
        
        // 解析外层结构:Story是列表,每个元素是单键字典(键为剧情标题,值为DialogSequence列表)
        var storyData = JsonConvert.DeserializeObject<StoryContainer>(jsonString);
        
        // 遍历所有剧情节点
        foreach (var chapter in storyData.Story)
        {
            // 取出章节标题和对应的DialogSequence列表
            foreach (var kvp in chapter)
            {
                string chapterTitle = kvp.Key;
                List<DialogSequence> dialogs = kvp.Value;
                
                // 这里处理剧情逻辑,比如打印测试
                Debug.Log($"章节:{chapterTitle},包含{dialogs.Count}段对话");
            }
        }
    }
}

// 定义外层容器类
public class StoryContainer
{
    public List<Dictionary<string, List<DialogSequence>>> Story { get; set; }
}

3. 若坚持使用Unity自带JsonUtility(需调整JSON结构)

如果不想引入第三方库,需要修改JSON结构,把动态键改成固定属性名,比如:

{
  "Story": [
    {
      "ChapterTitle": "Title1",
      "Dialogs": [
        {
          "TextDialog": "",
          "TextNameCharacter": "",
          "SpriteCharacterPath": "",
          "SpriteBackgroundPath": "",
          "ChoiceMultiple": false,
          "TextChoice": ["Next"],
          "IndexChoice": ["Title2"]
        }
      ]
    },
    {
      "ChapterTitle": "Title2",
      "Dialogs": [...]
    }
  ]
}

然后定义对应的C#类:

[System.Serializable]
public class ChapterData
{
    public string ChapterTitle;
    public DialogSequence[] Dialogs;
}

[System.Serializable]
public class StoryContainer
{
    public ChapterData[] Story;
}

最后反序列化:

var storyContainer = JsonUtility.FromJson<StoryContainer>(jsonString);
// 访问storyContainer.Story获取所有章节数据

补充说明

  • 如果你无法修改Twine导出的JSON结构,强烈推荐使用Newtonsoft.Json,它能完美适配动态键场景,无需调整JSON。
  • 加载Sprite时,确保路径正确:如果用Resources.Load,路径要去掉文件扩展名和Resources前缀,比如图片在Resources/Sprites/Characters/Alice.png,路径就写Sprites/Characters/Alice。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:55:09