Unity C#

GameObject в Unity C#: создание, поиск и управление объектами

GameObject в Unity — базовый класс для всех объектов, которые могут существовать в сцене: персонажи, декорации, источники света, камеры. Сам по себе GameObject пуст — это контейнер для компонентов, которые определяют, как объект выглядит и ведёт себя.

Устройство

  • GameObject — это контейнер: компоненты вешаются на него через инспектор или AddComponent.
  • Любой скрипт, наследующий MonoBehaviour, можно добавить на GameObject как компонент.
  • Из собственного скрипта объект доступен через свойство gameObject.
  • Событийные функции (Update и другие) вызываются, только если объект активен: одновременно верны activeSelf и activeInHierarchy.

Создание объекта из кода

Самый простой способ — конструктор. В примере из документации Unity создаётся пустой объект с компонентом AudioSource за один вызов:

using UnityEngine;

public class ObjectFactory : MonoBehaviour
{
    void Start()
    {
        // Имя + типы компонентов через параметры конструктора
        GameObject go = new GameObject("myExampleGO", typeof(AudioSource));
        Debug.Log("Создан объект: " + go.name);
    }
}

Но чаще объекты клонируют из префабов — там уже настроены компоненты, свойства и дочерние объекты. Подробно это разбирается в статье Instantiate в Unity C#.

Основные свойства

Свойство Что возвращает
activeSelf Локальное состояние активности объекта (только чтение)
activeInHierarchy Активен ли объект с учётом всех родителей (только чтение)
tag Метка объекта — для поиска и группировки
layer Номер слоя: физика, рендеринг, рейкасты
isStatic Статический ли объект (флаги статичности)
scene Сцена, в которой находится объект

Разница между activeSelf и activeInHierarchy принципиальна: дочерний объект может быть «включён локально», но выключен вместе с родителем — тогда activeSelf равен true, а activeInHierarchy равен false.

Включение и выключение

using UnityEngine;

public class ToggleDemo : MonoBehaviour
{
    public GameObject panel;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab) && panel != null)
        {
            // Переключатель: включает выключенное, выключает включённое
            bool next = !panel.activeSelf;
            panel.SetActive(next);
            Debug.Log("Панель активна: " + next);
        }
    }
}

Учтите: при выключении объекта корутины, запущенные его компонентами, останавливаются (активность объекта, а не enabled компонента), а при повторном включении Awake не вызывается заново — он срабатывал при первой активации.

Поиск объектов

Метод Особенности
GameObject.Find("Имя") Ищет по имени среди активных объектов. Медленный: перебор всей сцены
GameObject.FindWithTag("Метка") Поиск по тегу, быстрее имени. Возвращает первый найденный
GameObject.FindGameObjectsWithTag Все объекты с тегом
FindAnyObjectByType Любой активный объект указанного типа (современный API Unity)
FindObjectsByType Все объекты указанного типа

Правило производительности: не ищите объекты в Update. Результат поиска кэшируйте в Awake или Start.

GameObject и Transform

На каждом GameObject есть хотя бы один компонент — Transform, отвечающий за позицию, вращение и масштаб. Поэтому transform доступен напрямую, без GetComponent, а доступ к родителю и детям идёт через него.

Частые ошибки

1. GameObject.Find каждый кадр

Полный перебор объектов сцены в Update — путь к просадке FPS. Кэшируйте при старте.

2. Путаница activeSelf и activeInHierarchy

Проверка panel.activeSelf вернёт true даже у объекта, чей родитель выключен. Для «видим ли объект сейчас» проверяйте activeInHierarchy.

3. Поиск выключенных объектов

Find и FindWithTag не видят неактивные объекты. Если цель может быть выключена — ищите через FindObjectsByType с включением неактивных или держите ссылку заранее.

4. Сравнение с настоящим null

Unity переопределяет оператор ==: уничтоженный через Destroy объект не равен C#-null, но равен null с точки зрения Unity. Сравнивайте с null напрямую — Unity-оператор обработает это корректно.

Связанные статьи