首页 > 解决方案 > Unity - 从服务器显示 Json 数组

问题描述

我正在制作一个问答游戏,但我遇到了这个可能很容易解决的问题。
我有这个脚本,它从服务器获取 JSON 数据并将其分离:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System;
using TMPro;

[Serializable]
public class RootObject
{
    public Results[] Result;
}

[Serializable]
public class Results
{
    public string id;
    public string question;
    public string answer1;
    public string answer2;
    public string answer3;
    public string answer4c;
}

public class DataLoader : MonoBehaviour
{
    public PickPlace pickplace;
    public string URLBase;

    public void GetQustion()
    {
        URLBase = pickplace.url;
        StartCoroutine(Run());
    }

    IEnumerator Run()
    {
        var req = CreateReturnPlayerDataRequest();
        yield return req.SendWebRequest();
        var results = HandleReturnPlayerDataRequest(req);
        // Izvada konsolē saņemtos datus
        Debug.Log("Quesiton: " + results.Result[0].question + " Answer1: " + results.Result[0].answer1 + " Answer2: " + results.Result[0].answer2 + " Answer3: " + results.Result[0].answer3 + " Answer4: " + results.Result[0].answer4c);

    }

    public UnityWebRequest CreateReturnPlayerDataRequest()
    {
        var req = UnityWebRequest.Get(URLBase);
        return req;
    }

    public static RootObject HandleReturnPlayerDataRequest(UnityWebRequest req)
    {
        if (req.isNetworkError)
        {
            Debug.LogError("Failed to POST /player/register");
            return new RootObject();
        }
        var results = JsonUtility.FromJson<RootObject>("{\"Result\":" + req.downloadHandler.text + "}");
        return results;
    }

}

我的问题是:
如何调用数组,例如我的GameManager脚本并调用分离的数据,以便我可以将 JSON 数据中的问题文本放入 Text 对象和按钮的所有 4 个答案?

标签: c#jsonunity3d

解决方案


目前你有一种方法来启动请求,但你永远不会等到/知道它什么时候完成!

我会简单地使用Action<RootObject>as 参数,这样您就可以添加一个回调侦听器并在调用它时对结果做出反应。

public class DataLoader : MonoBehaviour
{
    public PickPlace pickplace;
    public string URLBase;

    public void GetQuestions(Action<RootObject> onSuccess)
    {
        URLBase = pickplace.url;

        StartCoroutine(Run(onSuccess));
    }

    IEnumerator Run(Action<RootObject> onSuccess)
    {
        var req = CreateReturnPlayerDataRequest();

        yield return req.SendWebRequest();

        var results = HandleReturnPlayerDataRequest(req);

        if(results == null)
        {
            yield break;
        }

        Debug.Log("Quesiton: " + results.Result[0].question + " Answer1: " + results.Result[0].answer1 + " Answer2: " + results.Result[0].answer2 + " Answer3: " + results.Result[0].answer3 + " Answer4: " + results.Result[0].answer4c);

        // Now invoke the Callback so whoever started the post call gets the results
        onSuccess?.Invoke(results);
    }

    public UnityWebRequest CreateReturnPlayerDataRequest()
    {
        var req = UnityWebRequest.Get(URLBase);
        return req;
    }

    private RootObject HandleReturnPlayerDataRequest(UnityWebRequest req)
    {
        if(req.isHttpError || req.isNetworkError)
        {
            Debug.LogError($"Failed to POST /player/register! Failed with {req.responseCode} - Reason: {req.error}");
            onDone?.Invoke(null);
            return null;
        }

        var results = JsonUtility.FromJson<RootObject>("{\"Result\":" + req.downloadHandler.text + "}");
        return results;
    }
}

所以现在你可以从另一个类中调用它,例如

// Drag these in via the Inspector
[SerializeField] private DataLoader dataLoader;
[Space]
[SerializeField] private Text questionText;
[Space]
[SerializeField] private Text button1Text;
[SerializeField] private Text button2Text;
[SerializeField] private Text button3Text;
[SerializeField] private Text button3Text;

public void SomeMethod()
{
    // Do the post call and react once the results are there either as lambda expression
    dataLoader.GetQuestions(results => {
        Debug.Log("Successfully received data. Will update GUI", this);

        // do something with the results now e.g.
        var first = results.Result[0];

        questionText.text = first.question;
        button1Text.text = first.answer1;
        button2Text.text = first.answer2;
        button3Text.text = first.answer3;
        button4Text.text = first.answer4;
    });

    // alternatively you can do the same also using a method
    dataLoader.GetQuestions(OnPostRequestFinished);
} 

private void OnPostRequestFinished(RootObject results)
{
    Debug.Log("Successfully received data. Will update GUI", this);

    // do something with the results now e.g.
    var first = results.Result[0];

    questionText.text = first.question;
    button1Text.text = first.answer1;
    button2Text.text = first.answer2;
    button3Text.text = first.answer3;
    button4Text.text = first.answer4;
}

推荐阅读