如何在Unity中读取JSON以创建对象数组?

v440hwme  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(74)

我目前正在Unity中进行一个Visual Novel项目。
为了制作这个故事,我使用了这个网站:https://twinery.org/来制作脚本和按钮的行为。制作了一个js脚本来将其转换为json,然后尝试将其导入Unity。
但问题是:当我把JSON阅读到Unity中时,我完全迷失了方向。
我有一个存储故事的“序列”的类:

public class DialogSequence : MonoBehaviour
{
    public string TextDialog; // The text that should be written in a box
    public string TextNameCharacter; // The name of the character on the display
    public Sprite SpriteCharacter; // The location where the image of the character is
    public Sprite SpriteBackground; // The location where the image of the background is
    public bool ChoiceMultiple; // If there is multiple choices or not
    public string[] TextChoice; // The text that should be written on the buttons (4 buttons at most)
    public string[] IndexChoice; // The index/key of the array where the next scene is stored at
}

字符串
json看起来像这样:

{
  "Story": [
    {
      "Title1": [
        {
          "TextDialog": "",
          "TextNameCharacter": "",
          "SpriteCharacter": "",
          "SpriteBackground": "",
          "ChoiceMultiple": false,
          "TextChoice": [
            "Next"
          ],
          "IndexChoice": [
            "Title2"
          ]
        }
      ]
    },
    {
      "Title2": [
        {
          "TextDialog": "",
          "TextNameCharacter": "",
          "SpriteCharacter": "",
          "SpriteBackground": "",
          "ChoiceMultiple": false,
          "TexteChoice": [
            "Next"
          ],
          "IndexChoice": [
            ""
          ]
        }
      ]
    }
    // [... + more than 180 objects]
  ]
}


我试着使用[System.Serializable]它不工作。我试着使用JSONUtility与类似JsonUtility.FromJson<DialogSequence[]>(jsonString);的东西,但它总是输出一个错误看起来像这样:

ArgumentException: Return type must represent an object type. Received an array.
UnityEngine.JsonUtility.FromJson (System.String json, System.Type type) (at <b3935cb894394494ac117685fb6e14c7>:0)

UnityEngine.JsonUtility.FromJson[T] (System.String json) (at <b3935cb894394494ac117685fb6e14c7>:0)
MainGame.Start () (at Assets/Scripts/MainGame.cs:24)


请注意,每个Story[*].TitleX属性都有不同的故事标题。此外,属性名称不是“Title 1 -2-... -180”,我只是更改了它,以便它更具可读性,更容易理解。
如何正确地将JSON转换为DialogSequence数组?

iyzzxitl

iyzzxitl1#

当您将JSON转换为某种类型T时,无论您使用哪种序列化器,T的数据模型都必须匹配根JSON容器的模式。在您的情况下,根JSON容器看起来像:

{
  "Story": [
    {
      "TitleX": [ /* An array of DialogSequence objects */ ]
    }
    // Additional Story objects with TitleX properties.
  ]
}

字符串
其中"TitleX"名称在运行时会有所不同。正如你所看到的,这并不对应于DialogSequence对象数组。
为了实现这一点,你的根数据模型需要看起来像:

public class Root
{
    public List<Dictionary<string, List<DialogSequence>>> Story { get; set; } = new();
}


现在,如this answer by Programmer中所述,JsonUtility不支持字典,因此您需要通过包管理器添加com.unity.nuget.newtonsoft-json来安装Unity的官方Json.NET build email protected(https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@3.2/manual/index.html)。
完成后,您现在可以将其转换并投影到DialogSequence对象数组,如下所示:

var root = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(jsonString);

DialogSequence [] dialogs = 
    root.Story.SelectMany(d => d.Values).SelectMany(v => v).ToArray();


可能还需要修改DialogSequence并将Sprite属性更改为字符串,然后在格式化完成后加载实际的sprites:

public class DialogSequence : MonoBehaviour
{
    // Changed from Sprite to string
    public string SpriteCharacter; // The location where the image of the character is
    // Changed from Sprite to string
    public string SpriteBackground; // The location where the image of the background is


在JSON中,这些属性存储为字符串,因此您的序列化数据模型需要与之匹配,或者您需要编写custom converter来处理转换。参见例如How to load sprite from JSON?
演示小提琴here

相关问题