Все классы в Unity Engine наследуются от Unity-Object, в том числе GameObject’ы и Component’ы. (Важно помнить, что GameObject и Component никак между собой не унаследованы) ### Instantiate Метод добавляет на сцену копию экземпляра GameObject. Сцена используется та, что открыта на данный момент в игре. `templateGameObject`- Какой GM нужно скопировать. `canvas.transform` - Можно указать какой GameObject будет родителем. ```csharp //Загружаем из папки Resources префаб GameScreen var templateGameObject = Resources.Load<GameScreen>("Prefabs/UI/GameScreen"); ``` ```csharp result = GameObject.Instantiate(templateGameObject, canvas.transform); ``` Результатом будет, то что на скрине. Если есть приписка «(Clone)», то GameObject был создан с помощью метода Instantiate. ![Unity-Object (статичный класс)](images/Unity-Object%20(статичный%20класс).png) ##### object.Instantiate - gameobject создастся только в конце фрейма? Метод Instantiate в Unity создаёт копию объекта и возвращает его сразу же. Это не зависит от времени фрейма или цикла обновления. Однако следует заметить, что новые объекты не будут обновлены или отрисованы до следующего кадра. Их Start и Awake методы вызываются перед следующим Update после того, как объект был создан. Таким образом, хотя объект существует сразу после вызова Instantiate, его полный жизненный цикл начинается только с начала следующего кадра. Например, если вы создадите объект и затем немедленно попытаетесь взаимодействовать с его компонентами, они будут существовать, но их методы Start и Awake могут еще не быть вызваны. Это может привести к неожиданным результатам, если ваш код полагается на инициализацию, производимую в этих методах. <br> ### DestroyImmediate ```csharp Object.DestroyImmediate(); ``` Метод удаляет Unity-Object из Editor-кода. Нельзя удалять Unity-Object из Editor-кода с помощью Destroy(), Unity выдаст ошибку. метод, предоставляемый Unity для немедленного удаления объекта. Он отличается от обычного метода Destroy тем, что он удаляет объект сразу же, не дожидаясь конца кадра. Но с этим методом нужно быть осторожным. Если объект, который вы пытаетесь удалить с помощью DestroyImmediate, все еще участвует в активной логике (например, он является частью выполняющегося в данный момент цикла обновления), это может вызвать непредсказуемое поведение или даже ошибки. В целом, Destroy предпочтительнее использовать, поскольку он безопасен и автоматически управляется Unity. DestroyImmediate следует использовать только в специальных случаях, когда вам действительно нужно сразу же удалить объект. Это часто используется в редакторском коде, когда вы хотите удалить объект во время работы в редакторе, а не во время выполнения игры. Еще одна важная деталь - DestroyImmediate не может быть вызван внутри цикла foreach, поскольку это может привести к изменению коллекции во время итерации, что вызовет ошибку. Вместо этого следует использовать обычный цикл for, итерирующийся в обратном порядке. <br> ### Destroy Метод удаляет Unity-object ```csharp Object.Destroy(); ``` Объекты уничтожаются немедленно после текущего цикла Update, или через t секунд, если указано время. Фактическое уничтожение объекта всегда откладывается до окончания текущего цикла Update, но всегда происходит перед рендерингом ##### Если удалить дочерний gm через Destroy, а в след. строчке кода проверить, есть ли у родителя дочка, то что ответит child.childCount? Если вы удаляете дочерний GameObject через Destroy(), а затем немедленно проверяете transform.childCount у родительского GameObject, то счетчик детей все еще будет включать уничтожаемый объект. Это происходит потому что Destroy() не удаляет объект мгновенно. Вместо этого, Unity отмечает объект для удаления и затем уничтожает его в конце кадра, после всех операций обновления и рендеринга. Поэтому, если вы проверяете transform.childCount в той же функции обновления, где вызываете Destroy(), то изменение еще не будет отражено. Вот пример: ```csharp void Update() { if (Input.GetKeyDown(KeyCode.Space)) { Destroy(transform.GetChild(0).gameObject); Debug.Log(transform.childCount); // Will still include the destroyed child. } } ``` В этом примере, если у родительского GameObject было два дочерних объекта, Debug.Log() будет выводить 2, даже после того, как один из детей был уничтожен. Однако в следующем кадре transform.childCount будет обновлен и будет правильно отображать количество детей. ##### после вызова Destroy(gm) ##### gm будет доступен до конца фрейма или сразу же будет иметь null? Когда вы вызываете Destroy(gm), Unity помечает объект gm на удаление. Однако сам объект не удаляется немедленно. Он удаляется только после завершения текущего цикла обновления (Update loop), но до рендеринга следующего кадра. Если вы проверите gm сразу после вызова Destroy(gm), вы обнаружите, что объект все еще существует и все его компоненты доступны. Однако, если вы попытаетесь обратиться к gm в следующем цикле обновления или позже, вы получите null. <br> ### FindObjectOfType или FindObjectsOfType Метод `FindObjectsOfType<T>()` в Unity не находит отключенные gameobjects. Эти методы возвращают первый или все найденные GameObjects в сцене, которые содержат указанный тип компонента. Обратите внимание, что эти методы производят поиск по всем объектам в сцене и могут быть довольно медленными, поэтому следует использовать их с осторожностью. Если возможно, лучше хранить ссылки на объекты, которые вам нужно часто искать, или использовать другие методы для организации и доступа к вашим объектам. если метод FindObjectOfType или FindObjectsOfType не найдет ни одного объекта с указанным компонентом, то FindObjectOfType вернет null, а FindObjectsOfType вернет пустой массив. Применение: - Поиск GameObject’а на сцене, через нахождение компонента - Нахождение Component’а на сцене ```csharp var canvas = Object.FindObjectOfType<Canvas>(); ``` Поиск нескольких Unity-Object’ов. ```csharp var canvasArray = Object.FindObjectsOfType<Canvas>(); ``` <br> ### DontDestroyOnLoad Метод маркирует GameObject, чтобы он не уничтожился при смене сцены. ```csharp Object.DontDestroyOnLoad(anyGameObject); ```