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 来检索精灵。
可以在回调中使用。
在 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 来检索精灵。 可以在回调中使用。