Дает возможность разработчику загружать файлы из проекта с помощью кода в Runtime.
При использовании `Resources.Load` ассеты не выгружаются из ОЗУ автоматически, а остаются в памяти, что может вызвать утечки и тормоза. Ассет останется в памяти до тех пор, пока игра работает или пока она не будет выгружена вручную. Unity не предоставляет автоматического управления памятью для ассетов, загруженных через `Resources`, поэтому каждый такой ассет занимает место в памяти, пока его не выгрузят явно.
Все ассеты из папки `Resources` добавляются в игру, даже если они не используются в каждом уровне. Это может сделать билд слишком большим, особенно для мобильных платформ или веб-игр.
Мы создаем папку под названием «Resources». Именно такое название, никак иначе. Папку можно создать в любой иерархии Unity Asset. Можно создавать множество таких папок в разных директориях.
Для работы с папкой Resources используется одноименный класс Resources.
<br>
Метод ищет файл по указанному пути. Путь указывается относительно папки Resources. В дженерике указывается тип, который мы ожидаем получить.
В данном примере, мы хотим загрузить префаб
```csharp
var result = Resources.Load<GameObject>("Prefabs/UI/GameScreen");
```
<br>
Если мы хотим загрузить на сцену префаб из папки Resources и нам также нужно получить компонент из этого префаба, то мы можем сразу указывать тип привязанного к префабу компонента.
Если мы будем изменять состояние префаба через `gameScreenObj`, то изменения коснуться не копии префаба, а самого файла префаб, который находится в папке resources.
```csharp
//Загружаем из папки Resources префаб GameScreen
var gameScreenObj = Resources.Load<GameScreen>("Prefabs/UI/GameScreen");
```
Далее, нужно добавить gameObject на сцену. Будет использоваться та сцена, которая активна на данный момент.
```csharp
//Добавляем GameScreen на сцену
//и получаем экземпляр GameScreen, что является компонентом GameObject'а GameScreen
_gameScreen = GameObject.Instantiate(gameScreenObj, canvas.transform);
```
<br>
Как правильно указать путь до файла, который мы хотим загрузить?
Нажимаем ПКМ по файлу и выбираем «Copy Path».
У нас получится вот такой путь:
Assets/Content/Resources/UI/Inventory/Item.prefab
А использовать путь в методе `Resources.Load` мы должны вот такой:
UI/Inventory/Item
<br>
Загружает все файлы из папки, кастуя в GameObject.
```csharp
var resultArray = Resources.LoadAll<GameObject>("Prefabs/UI/");
```
<br>
Можно загрузить файл асинхронно (в отдельном потоке). Обработать результат можно через Coroutine.
```csharp
private void Start()
{
var result = Resources.LoadAsync<GameObject>("Prefabs/UI/GameScreen");
StartCoroutine(Loading(result));
}
private GameObject asset;
public IEnumerator Loading(ResourceRequest rr)
{
while (rr.isDone == false)
{
yield return null;
}
asset = rr.asset as GameObject;
}
```
<br>
### Примеры управления памятью с помощью `Resources`
Чтобы выгрузить ассет из памяти, можно использовать метод `Resources.UnloadAsset` или `Resources.UnloadUnusedAssets`:
```csharp
GameObject loadedModel = Resources.Load<GameObject>("path/to/your/model");
// После использования:
Resources.UnloadAsset(loadedModel);
```
или
```csharp
// Этот метод выгружает все неиспользуемые ресурсы из памяти:
Resources.UnloadUnusedAssets();
```
Однако для крупных ассетов, таких как `.fbx` модели, такой подход может привести к задержкам, особенно если вызов `Resources.UnloadUnusedAssets` идет на больших объемах данных. Поэтому для гибкого управления памятью лучше использовать `Addressables`, так как они позволяют загружать и выгружать ассеты более контролируемо.
### Resources.LoadAsync выполняется в одном потоке или в многопотоке?
В Unity, метод Resources.LoadAsync выполняется в одном потоке.
Этот метод загружает ресурсы асинхронно, но все еще выполняет эту операцию в основном потоке приложения Unity. Это означает, что если вы используете LoadAsync для загрузки больших файлов, это может замедлить работу вашего приложения, поскольку это приведет к блокировке основного потока на время загрузки.
ChatGPT-3.5
<br>