当同一个项目在编辑器中正常工作时,在 Webgl 构建上出现解析错误

Getting a parse error on Webgl build while same project works fine in editor

我正在 Unity Webgl 上做一个项目,只有在构建项目时才会出错(在编辑器中它工作正常)。基本上我使用 Jsonblob link 将参数分配给我制作的自定义结构。

错误提示:Could not parse response {object}. Exception has been thrown by the target of an invocation. {object} 是我在 jsonblob 网站中使用的 json。

我使用的结构如下所示:

public struct GameSettings
{
    public String venueName { get; set; }
    public Monitor[] monitors { get; set; }
    public Flag[] flags { get; set; }
    public InformationMonitor[] informationMonitors { private get; set; }
    public Banner[] banners { get; set; }
    private const int MAX_MONITOR_LENGHT = 4;
}

虽然我获取数据并分配数据的函数如下所示:

public GameSettings gameSettings;

public void Awake()
{
    isRecovered = false;
    GetData((response) => {
        isRecovered = true;
        gameSettings = response;
    });
}

public async void GetData(System.Action<GameSettings> callback)
{
    var url = jsonURL;

    var httpClient = new HttpClient(new JsonSerializationOptions());
    var result = await httpClient.Get<GameSettings>(url);
    callback(result);
}

正如错误所说,它似乎无法解析对象,虽然我不太明白为什么会这样,尤其是当项目在编辑器中正常运行时为什么会发生这种情况,我是不是漏掉了什么?

由于 WebGL 既不支持 multi-threading 也不支持 async,因此 HttpClient 在 WebGL 上根本不受支持(另请参阅 )。

您应该使用 UnityWebrequest.Get and for the JSON deserialization either use the built-in JsonUtility or Newtonsoft Json.NET which comes as a Package 并预装在最新版本中。

例如像

// In order to use the built-in serializer your types need to be [Serializable]
[Serializable]
public struct GameSettings
{
    private const int MAX_MONITOR_LENGHT = 4;

    // Note that all nested types also need to be [Serializable]
    // Also at least the built-in JsonUtility only supports fields by default, no properties
    // so either make them all fields or use Newtonsoft
    // or enforce serialization using the undocumented [field: SerializeField] for each property
    public string venueName;
    public Monitor[] monitors;
    public Flag[] flags;
    public InformationMonitor[] informationMonitors;
    public Banner[] banners; 
}

public GameSettings gameSettings;
public string jsonURL;

// Start can be a Coroutine, if it returns IEnumerator it is automatically 
// statred as a Coroutine by Unity
private IEnumerator Start()
{
    isRecovered = false;
    
    // you can simply yield another IEnumerator 
    yield return GetData();
}

private IEnumerator GetData()
{
    using(var www = UnityWebRequest.Get(jsonURL))
    {
        // Request and wait for the result
        yield return www.SendWebRequest();

        if(www.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"failed due to \"{www.error}\"", this);
            yield break;
        }

        // now this depends on how good your types are (de)serializable
        // either the built-in way
        gameSettings = JsonUtiltiy.FromJson<GameSettings>(www.downloadHandler.text);
        // or directly using Newtonsoft
        gameSettings = JsonConvert.DeserializeObject<GameSettings>(www.downloadHandler.text);


        isRecovered = true;
    }
}