Unity 在场景中异步加载 www 图片

Unity load www images in scene async

在 Unity 中,我有一个主屏幕。当我点击它时,我想打开一个场景,其中包含带有缩图 (900x900) 的游戏列表。

我的问题是 Unity 不加载 "loadasync" 部分中的图像。这是我的代码:

主页异步加载下一个场景的代码(在 OnPointerClick 中调用)

IEnumerator LoadSceneAsyncIEnumerator(string sceneName)
{
    yield return null;
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
    while (!asyncLoad.isDone)
    {
        yield return null;
    }
}

这是我的 ListGames 场景的觉醒:

void Awake(){
    List<JeuIO> jeux = GetGames ();
    foreach (JeuIO j in jeux){
        StartCoroutine(LoadImageAsync(j.image1));
    }
}

GetGames 执行 http 调用以获取游戏列表(在场景打开之前完成),但 LoadImageAsync 在 asyncLoad.isDone == true 之前未解析。

IEnumerator LoadImageAsync(string url) {
    string u = url;
    bool found = false;
    if (File.Exists(Application.persistentDataPath + "/"+url.GetHashCode()+".png")){
        u = Application.persistentDataPath + "/"+url.GetHashCode()+".png";
        found = true;
    }

    WWW www = new WWW(u);
    yield return www;

    Texture2D t = null;
    if(!found && www.bytes != null) {
        File.WriteAllBytes(Application.persistentDataPath + "/"+url.GetHashCode()+".png", www.bytes);
        t = www.textureNonReadable;
    } else {
        t = www.texture;
    }
    if (t != null){
        Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
    }
    Debug.Log("IMAGE "+url+" OVERRRRRRRR");
}

当然这不是最终代码 ^^ 我将直接在网格的游戏对象中创建精灵。

那么,我怎样才能在等待完成之前强制 unity 创建我所有的精灵?

在我看来,您的 loadscene 脚本和 ListGames 脚本没有以任何方式连接。所以目前没有办法强制这种行为。

有多种方法可以解决您的问题。 解决方案可能是:

将您的 List<JeuIO> jeux 移动到一个 ScriptableObject,您可以选择将其作为参数传递给您的 LoadScene 脚本。这样您就可以保持某种形式的代码灵活性和可扩展性。

其次,您可能想在 LoadImageAsync 方法中实现回调函数:

IEnumerator LoadImageAsync(string url, Action<Sprite> callback) {
    // your code
    var sprite Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));


    callback?.Invoke(sprite);
}

这样实现:

IEnumerator LoadSceneAsyncIEnumerator(string sceneName, SomeScriptableObject scriptable)
{
    yield return null;
    var targetCount = scriptable.jeux.Count();
    var loadedCount = 0;

    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
    foreach (var j in scriptable.jeux)
    {
        // for each image that is processed, increment the counter
        StartCoroutine(LoadImageAsync(j.image1,(sprite) =>
        {
            someList.Add(sprite);
            loadedCount++;
        }));
    }

    while (!asyncLoad.isDone || targetCount != loadedCount)
    {
        yield return null;
    }
}

编辑: 您可以通过将参数传递给 Action 来检索精灵。 可以在回调中使用。