Войти
UnityФорумПрограммирование

LoadAssetAsync, несколько базовых вопросов, подскажите плз.

#0
10:59, 25 ноя. 2021

Начал делать подгрузку ресурсов, есть несколько нубских вопросов, подскажите пожалуйста для понимания и построения дальнейшей  конструкции программы... Пока вроде в С# никаких утечек не замечено, что бы не делалось, но тут уже заходит речь о возможной потере указателей и такое вполне, думаю, будет возможно, а не хотелось бы.

Вот для примера, процедура загрузки объекта помеченного как Addressables:

public void LoadObj(object Name, int Test)
    {
        AsyncOperationHandle<GameObject> ObjHande = Addressables.LoadAssetAsync<GameObject>(Name);

        ObjHande.Completed += (Obj) =>
        {
            if (Obj.Status != AsyncOperationStatus.Succeeded) return;
            LoadedGameObject = Obj.Result;
            TestTextLinc.text = TestTextLinc.text + "\n" + ObjHande.Status + "\n" + LoadedGameObject.name + "\n";
            print(Test);
            Addressables.ReleaseInstance(Obj);            
        };      
    }

Есть ли у загруженного ObjHande какой-то идентификатор, что бы можно было однозначно соотнести (не по входящему Name) c загружаемым префабом в редакторе? То есть понимать, что ObjHande это C:\test\123\name.png? Если нет, есть ли способ это как-то сопоставить?

Можно ли как-то соотнести инстанциированный объект на сцене (LoadedGameObject) с тем, что находится в редакторе, типа: C:\TEST\123\name.png это такой-то объект на сцене?

ObjHande и Obj это одно и то же? Или надо сохранять/очищать 2 переменные ObjHandle и Obj (мало ли)?       

Если не очистить ObjHandle и не сохранить ссылку, можно ли как-то ее получить?

Если не сохранить ссылку, можно ли как-то очистить ObjHande? (Удалить все объекты созданные из него, не знаю...)

Как правильно организовать возврат результата? (Ожидать значения надо где-то в потоке, думаю). Предполагаю, что эту надо вызвать в потоке, что бы можно было разом грузить несколько объектов, на вход дать указатель на переменную куда положить результат. (То есть из нескольких потоков вызывать эту функцию)

По пункту выше, что будет если текущую асинхронную функцию вызвать в цикле for (и передавать новую переменную куда писать результат, ожидать где-то в корутине), при условии, что каждый новый объект будет грузиться дольше, чем работает весь цикл for целиком, запуститься несколько копий процедуры, или сработает последний вызов? (Что делать с памятью остальных вызовов (надо ли делать ReleaseInstance всего что вызывали в for))

Ссылка на загруженный GameObject (LoadedGameObject) понятна, что делать с ObjHande/Obj? Если он больше не нужен, (но сам объект (LoadedGameObject) нужен), его надо очищать (Addressables.ReleaseInstance)? Не пропадет объект LoadedGameObject?

Перед очищением ObjHandle надо ли очищать/удалять все LoadedGameObject?


#1
(Правка: 13:18) 13:16, 25 ноя. 2021

Слишком много букв и куски сознания, типа "утечек нет но может что то сделать?"

я пользовался когда делал игру
AssetBundle
тык

Вот тебе примерно кучку, смотри как там делают. Возможно куча вопросов исчезнет.
И почитай что такое карутины и с чем их кушают и не будет вопросов насчет for

примеры

зы и разбирись как в юнити организуется жизненный цикл обьектов. Это по тому куску сознания насчет потока.

#2
(Правка: 26 ноя. 2021, 11:16) 14:23, 25 ноя. 2021

>DanQuimby
AssetBundle, не совсем то что надо. И да там их не потерять, как я понимаю.

примеры

Загрузку выгрузку и инстанциирование, всего что нужно я и так делаю.
Я вроде вопросы конкретные задал (может неправильно применил терминологию), на них ответы да - нет, по большей части.
куски сознания

Был бы очень признателен если бы вы ответили на эти куски. Мне будет достаточно этого для реализации. (Пока по крайней мере так думаю.)
не будет вопросов насчет for

Это вы про что? Вопрос совершенно в другом.
Вызвать 1 процедуру  1  раз из 10 потоков...
Вызвать 1 процедуру 10 раз из 1 потока...
(С первым вариантом понятно, а вот со вторым при реализации, как у меня в примере... что будет на выходе в LoadedGameObject ???)

  • корутины использую только если что-то надо по быстрому налепить. Я использую await/async
  • Спасибо за ссылку, есть немного чего не видел ранее.
  • В частности вот:

    Важный момент - не удаляйте объекты через Destroy, или после обычного Destroy вызывайте Addressables.ReleaseInstance на объекте AsyncOperationHandle, тогда счётчик ссылок, который помогает Addressables выгружать ненужное, будет правильно понимать сколько ссылок осталось и вовремя выгрузит лишнее из памяти.
    Так же инстанциируйте через Addressables.InstantiateAsync, это тоже связано со счётчиком. Загрузка через LoadAsync с последующим инстанциированием "как обычно" приведёт к тому, что Addressables не будет знать что выгружать надо, а что нельзя.

    Я вот как бы собираюсь сам следить за всеми объектами, что по человечески нельзя написать?
    Если я сделаю  LoadAssetAsync, а потом кучу instantiate, для объекта, а потом сам сделаю Destroy всем объектам (сам все посчитаю и тд) и потом сделаю Addressables.ReleaseInstance ... Так все выгрузится или нет?

    Я поражаюсь таким статьям... много умного написано, а как правильно использовать 1 строчка, что бы у всех все работало через одно место или сами не знают, что скорее всего. Есть все кроме основной информации, пипец.

    #3
    (Правка: 15:35) 15:21, 28 ноя. 2021

    Сам отвечу на свой вопрос после недели тестирования в LoadedGameObject будет фигня. Если возвращать ObjHande, а его надо возвращать, так же будет фигня.
    С попеременным успехом будут полезные/битые данные в зависимости от скорости выполнения и промежутков между загрузкой и ожиданием загрузки... (может будет правильно, а может последний объект будет в последних 3х, например, а те затрутся)
    А вот как раз LoadedGameObject возвращать собственно и не нужно, та как GameObject будет получен при инстанциировании.

    Будет именно то, что должно быть при: Вызвать 1 процедуру 10 раз из 1 потока... (где получается асинхронный результат приходящий в разное время), для адекватной работы корутины тут не катят.
    Вот с UniRX работает замечательно, только интересно не будет ли глюков на каких либо устройствах с ним.

    Так же по тому, что вижу пока, после загрузки получаем хендл: ObjHande
    Инстанциируем сколько нужно раз, потом по необходимости удаляем объекты, если объектов больше нет (все удалили), делаем ReleaceInstance хендлу. Вроде в памяти ничего не остается.

    UnityФорумПрограммирование