Как инстанциировать ассет асинхронно?
Johnson Дата: Сб, 08 Июн 2013, 20:42 | Сообщение # 1
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Здравствуйте, уважаемые. При инстанциации большой сцены возникает подвисание. Как его избежать? Ассет загружаю как обычно: Код
public IEnumerator InstantiateAsset(string assetName, OnProgress onProgress, OnLoaded onLoaded) { WWW asset = WWW.LoadFromCacheOrDownload("file://" + Application.dataPath + "/AssetBundles/" + assetName + ".unity3d", 2); while (!asset.isDone) { if (onProgress != null) onProgress(asset.progress); yield return null; } if (onProgress != null) onProgress(1f); yield return asset; AssetBundle assetBundle = asset.assetBundle; asset.Dispose(); Object go = Object.Instantiate(assetBundle.mainAsset, new Vector3(0, 0, 0), new Quaternion(0, 0, 0, 0)); go.name = assetName; assetBundle.Unload(true); if (onLoaded != null) onLoaded(); }
Не хочется игровой мир делить на слишком мелкие куски, чтобы не было подтормаживания при ходьбе...
Сообщение Здравствуйте, уважаемые. При инстанциации большой сцены возникает подвисание. Как его избежать? Ассет загружаю как обычно: Код
public IEnumerator InstantiateAsset(string assetName, OnProgress onProgress, OnLoaded onLoaded) { WWW asset = WWW.LoadFromCacheOrDownload("file://" + Application.dataPath + "/AssetBundles/" + assetName + ".unity3d", 2); while (!asset.isDone) { if (onProgress != null) onProgress(asset.progress); yield return null; } if (onProgress != null) onProgress(1f); yield return asset; AssetBundle assetBundle = asset.assetBundle; asset.Dispose(); Object go = Object.Instantiate(assetBundle.mainAsset, new Vector3(0, 0, 0), new Quaternion(0, 0, 0, 0)); go.name = assetName; assetBundle.Unload(true); if (onLoaded != null) onLoaded(); }
Не хочется игровой мир делить на слишком мелкие куски, чтобы не было подтормаживания при ходьбе... Автор - Johnson Дата добавления - 08 Июн 2013 в 20:42
Hunjeth Дата: Вс, 09 Июн 2013, 16:28 | Сообщение # 2
Сообщений: 354
Награды:
1
Репутация:
112
Статус: Offline
ну так сцена большя, никак побгдужать мир кусками : быстродействие малое потребление памяти быстро побгдужать мир целиком : зависания использует много памяти долго ждать можно : использовать LOD или окно згрузки как в ксс например
Сообщение отредактировал Hunjeth - Вс, 09 Июн 2013, 16:38
Сообщение ну так сцена большя, никак побгдужать мир кусками : быстродействие малое потребление памяти быстро побгдужать мир целиком : зависания использует много памяти долго ждать можно : использовать LOD или окно згрузки как в ксс например Автор - Hunjeth Дата добавления - 09 Июн 2013 в 16:28
Johnson Дата: Вс, 09 Июн 2013, 16:44 | Сообщение # 3
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Про LOD (а точнее про Culling Occlusion) я думал уже... Но сомневаюсь. Мир планирую огромный (более 1000 кв. км.), поэтому вариант с полным миром не рассматривал изначально. Одни только терраины забьют память подчистую. Сейчас мир нарезан на чанки 1024*1024, при загрузке такого чанка клиент подвисает на секунду где-то... Если "неудачно" подошел в место, из которого загружается сразу 3 чанка - то вообще ад. Неприятно будет, если при путешествии по миру игроки будут постоянно подвисать. Локационный мир тоже не рассматриваю - игра онлайновая. В качестве локаций планирую только инстансы. PS: нарезать на ещё более мелкие чанки, думаю, абсурдно... Замучаемся сводить их.
Сообщение отредактировал Johnson - Вс, 09 Июн 2013, 16:50
Сообщение Про LOD (а точнее про Culling Occlusion) я думал уже... Но сомневаюсь. Мир планирую огромный (более 1000 кв. км.), поэтому вариант с полным миром не рассматривал изначально. Одни только терраины забьют память подчистую. Сейчас мир нарезан на чанки 1024*1024, при загрузке такого чанка клиент подвисает на секунду где-то... Если "неудачно" подошел в место, из которого загружается сразу 3 чанка - то вообще ад. Неприятно будет, если при путешествии по миру игроки будут постоянно подвисать. Локационный мир тоже не рассматриваю - игра онлайновая. В качестве локаций планирую только инстансы. PS: нарезать на ещё более мелкие чанки, думаю, абсурдно... Замучаемся сводить их. Автор - Johnson Дата добавления - 09 Июн 2013 в 16:44
Hunjeth Дата: Вс, 09 Июн 2013, 16:50 | Сообщение # 4
Сообщений: 354
Награды:
1
Репутация:
112
Статус: Offline
Occlusion Culling это не тоже самое что LOD для открытого мира лучше использовать LOD ибо у тебя видео карта загнется LOD : http://en.wikipedia.org/wiki/Level_of_detail Occlusion Culling : Wiki Цитата
Ситуация, в которой два объекта расположены приблизительно на одной линии и один объект, расположенный ближе к виртуальной камере или порту просмотра (англ. viewport), частично или полностью закрывает видимость другого объекта. В графическом конвейере (англ. Graphics pipeline) используется «окклюзивное обрезание» (англ. occlusion culling) для удаления скрытых поверхностей прежде, чем к ним начнут применяться растеризация и шейдеры.
Сообщение отредактировал Hunjeth - Вс, 09 Июн 2013, 16:55
Сообщение Occlusion Culling это не тоже самое что LOD для открытого мира лучше использовать LOD ибо у тебя видео карта загнется LOD : http://en.wikipedia.org/wiki/Level_of_detail Occlusion Culling : Wiki Цитата
Ситуация, в которой два объекта расположены приблизительно на одной линии и один объект, расположенный ближе к виртуальной камере или порту просмотра (англ. viewport), частично или полностью закрывает видимость другого объекта. В графическом конвейере (англ. Graphics pipeline) используется «окклюзивное обрезание» (англ. occlusion culling) для удаления скрытых поверхностей прежде, чем к ним начнут применяться растеризация и шейдеры.
Автор - Hunjeth Дата добавления - 09 Июн 2013 в 16:50
Johnson Дата: Вс, 09 Июн 2013, 17:13 | Сообщение # 5
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Знаю я что такое LOD. Я тут проводил эксперименты с размещением огромного количества хайполи объектов с лодом и без. Результаты мало отличаются, поэтому думается мне, что юнька сама полигоны совмещает (эта мысль есть ещё у нескольких человек, находил подобные ответы в сети). Но, пусть даже лод. Допустим, мир 100*100 чанков. Памяти не хватит в любом случае, ведь кроме терраинов есть ещё приличное количество объектов на нем. Есть ещё мысль каждый чанк разбивать на составляющие (например, терраин, деревья, здания, остальное) и грузить их по очереди. Насколько хорошая идея - не знаю, если ни чего лучше не придумаю - буду пробовать так.Добавлено (09 Июн 2013, 17:13) --------------------------------------------- Но всё же меня смущает отсутствие возможность инстанциировать объект по частям, асинхронно... Ведь в памяти в любом случае создается всё дерево объектов. Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно. Тогда бы проблем вообще не было - знай себе инстанциируй их в сопрограмме...
Сообщение Знаю я что такое LOD. Я тут проводил эксперименты с размещением огромного количества хайполи объектов с лодом и без. Результаты мало отличаются, поэтому думается мне, что юнька сама полигоны совмещает (эта мысль есть ещё у нескольких человек, находил подобные ответы в сети). Но, пусть даже лод. Допустим, мир 100*100 чанков. Памяти не хватит в любом случае, ведь кроме терраинов есть ещё приличное количество объектов на нем. Есть ещё мысль каждый чанк разбивать на составляющие (например, терраин, деревья, здания, остальное) и грузить их по очереди. Насколько хорошая идея - не знаю, если ни чего лучше не придумаю - буду пробовать так.Добавлено (09 Июн 2013, 17:13) --------------------------------------------- Но всё же меня смущает отсутствие возможность инстанциировать объект по частям, асинхронно... Ведь в памяти в любом случае создается всё дерево объектов. Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно. Тогда бы проблем вообще не было - знай себе инстанциируй их в сопрограмме...
Автор - Johnson Дата добавления - 09 Июн 2013 в 17:13
seaman Дата: Вс, 09 Июн 2013, 19:38 | Сообщение # 6
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
Цитата
Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно.
Не понял. А почему нельзя? AssetBundle.LoadAsync(имя ассета) - загружает конкретный ассет из бандла и асинхронно.
Сообщение Цитата
Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно.
Не понял. А почему нельзя? AssetBundle.LoadAsync(имя ассета) - загружает конкретный ассет из бандла и асинхронно.Автор - seaman Дата добавления - 09 Июн 2013 в 19:38
Johnson Дата: Вс, 09 Июн 2013, 20:25 | Сообщение # 7
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Дак загружает-то асинхронно, а инстанциировать-то приходится весь объект (долго). Код
Object go = Object.Instantiate(assetBundle.mainAsset, new Vector3(0, 0, 0), new Quaternion(0, 0, 0, 0));
Сообщение отредактировал Johnson - Вс, 09 Июн 2013, 20:26
Сообщение Дак загружает-то асинхронно, а инстанциировать-то приходится весь объект (долго). Код
Object go = Object.Instantiate(assetBundle.mainAsset, new Vector3(0, 0, 0), new Quaternion(0, 0, 0, 0));
Автор - Johnson Дата добавления - 09 Июн 2013 в 20:25
seaman Дата: Вс, 09 Июн 2013, 22:25 | Сообщение # 8
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
О чем Вы вообще пишете? Вы спросили (цитата): Цитата
Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно.
Я ответил - они это давным давно сделали. Вам никто не мешает в бандл засунуть хоть 100500 объектов и получить их отдельно упомянутой функцией. Далее. Если Вы инстанцируете сложный объект - это делается, конечно долго. Но Вы же сами предложили выход из ситуации (цитата): Цитата
знай себе инстанциируй их в сопрограмме...
Вопрос: все уже есть - что то еще надо? Как говорится - разделяй и властвуй!
Сообщение О чем Вы вообще пишете? Вы спросили (цитата): Цитата
Почему бы разработчикам не сделать возможность из бандла получать все объекты отдельно.
Я ответил - они это давным давно сделали. Вам никто не мешает в бандл засунуть хоть 100500 объектов и получить их отдельно упомянутой функцией. Далее. Если Вы инстанцируете сложный объект - это делается, конечно долго. Но Вы же сами предложили выход из ситуации (цитата): Цитата
знай себе инстанциируй их в сопрограмме...
Вопрос: все уже есть - что то еще надо? Как говорится - разделяй и властвуй! Автор - seaman Дата добавления - 09 Июн 2013 в 22:25
Johnson Дата: Пн, 10 Июн 2013, 08:37 | Сообщение # 9
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Никак не могу сообразить, что Вы имеете в виду. Сейчас я инстанциирую так: Object go = Instantiate(bundle.mainAsset); Но в корутине же всеравно оно так же будет добавляться в мир, а это займет время. Или я не прав? Можно увидеть Ваш вариант программы?
Сообщение Никак не могу сообразить, что Вы имеете в виду. Сейчас я инстанциирую так: Object go = Instantiate(bundle.mainAsset); Но в корутине же всеравно оно так же будет добавляться в мир, а это займет время. Или я не прав? Можно увидеть Ваш вариант программы? Автор - Johnson Дата добавления - 10 Июн 2013 в 08:37
seaman Дата: Пн, 10 Июн 2013, 10:23 | Сообщение # 10
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
В бандле может быть сколько угодно объектов. Разбиваете наиболее сложные на части и истанцируете по частям. Достать один префаб (цельный объект или часть большого) из бандла можно указанной функцией AssetBundle.LoadAsync. Чтобы не было тормозов достаем и инстанцируем не все сразу, а частями, размазывая во времени. Проще всего это сделать корутиной. Например. mainasset в бандле - это список всех ассетов в бандле ScriptableObject, в котором массив - имена всех ассетов в бандле. Достаем этот ассет. Код
string[] names = ((ScriptableObject)assetBundle.mainasset).names;
Используем его для того что бы достать все остальные ассеты. Код
StartCoroutine(InstantiateBundle(assetBundle, names));
Сама корутина: Код
IEnumerator InstantiateBundle(AssetBundle assetBundle, string[] names) { foreach(string name in names) { GameObject go = (GameObject) Instantiate(assetBundle.Load(name)); yield return null; } }
Тут не использовал асинхронную загрузку. Сам подумай как. ЗЫ: писал прямо в форуме, мог напортачить где то, так что проверяй. (даже знаю где )
Сообщение В бандле может быть сколько угодно объектов. Разбиваете наиболее сложные на части и истанцируете по частям. Достать один префаб (цельный объект или часть большого) из бандла можно указанной функцией AssetBundle.LoadAsync. Чтобы не было тормозов достаем и инстанцируем не все сразу, а частями, размазывая во времени. Проще всего это сделать корутиной. Например. mainasset в бандле - это список всех ассетов в бандле ScriptableObject, в котором массив - имена всех ассетов в бандле. Достаем этот ассет. Код
string[] names = ((ScriptableObject)assetBundle.mainasset).names;
Используем его для того что бы достать все остальные ассеты. Код
StartCoroutine(InstantiateBundle(assetBundle, names));
Сама корутина: Код
IEnumerator InstantiateBundle(AssetBundle assetBundle, string[] names) { foreach(string name in names) { GameObject go = (GameObject) Instantiate(assetBundle.Load(name)); yield return null; } }
Тут не использовал асинхронную загрузку. Сам подумай как. ЗЫ: писал прямо в форуме, мог напортачить где то, так что проверяй. (даже знаю где ) Автор - seaman Дата добавления - 10 Июн 2013 в 10:23
Johnson Дата: Пн, 10 Июн 2013, 18:37 | Сообщение # 11
Сообщений: 24
Награды:
0
Репутация:
0
Статус: Offline
Спасибо огромнейшее! То, что нужно! Про напортачить - это мне не страшно, мне нужно было понять сам алгоритм.Добавлено (10 Июн 2013, 18:37) --------------------------------------------- Ни как не могу разобраться...
Код
string[] names = ((ScriptableObject)assetBundle.mainasset).names;
Не работает. Нету у ScriptableObject поля names. Разобрался с функциями LoadAll и LoadAsync, но все равно шняга, они инстанциируют все лоды, и без скриптов. Помоги, пожалуйста, точнее
Сообщение Спасибо огромнейшее! То, что нужно! Про напортачить - это мне не страшно, мне нужно было понять сам алгоритм.Добавлено (10 Июн 2013, 18:37) --------------------------------------------- Ни как не могу разобраться...
Код
string[] names = ((ScriptableObject)assetBundle.mainasset).names;
Не работает. Нету у ScriptableObject поля names. Разобрался с функциями LoadAll и LoadAsync, но все равно шняга, они инстанциируют все лоды, и без скриптов. Помоги, пожалуйста, точнее Автор - Johnson Дата добавления - 10 Июн 2013 в 18:37