Unity - отображать Json массив с сервера - PullRequest
0 голосов
/ 03 апреля 2020

Я делаю игру-викторину, и я застрял в этой проблеме, которую, вероятно, легко сделать.
У меня есть этот скрипт, который получает 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 ответа на кнопки?

1 Ответ

0 голосов
/ 03 апреля 2020

В настоящее время у вас есть метод для запуска запроса, но вы никогда не ждете, пока / не узнаете , когда это будет сделано!

Я бы просто использовал Action<RootObject> в качестве параметра, чтобы вы могли добавьте прослушиватель обратного вызова и реагируйте на результат при его вызове.

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...