Unity 6.3
0 онлайн 8 гостей 3 в системе
Вход

Класс GameObject

Класс GameObject в Unity представляет всё, что может существовать в Scene. GameObjects являются строительными блоками для сцен в Unity и действуют как контейнер для функциональных компонентов, которые определяют, как выглядит GameObject и что он делает.

Класс GameObject класс содержит набор методов для работы с GameObject в коде. Среди них — поиск, установление связей и отправка сообщений между GameObject, добавление и удаление прикреплённых компонентов, а также задание значений, связанных с их состоянием в сцене.

Полный справочник по всем членам класса GameObject см. в Ссылка на скрипт GameObject.

Информацию об использовании GameObjects в Scene и Hierarchy в Unity Editor см. в Введение в GameObjects.

Scene свойства состояния

Все GameObjects разделяют набор контроля в верхней части Inspector касающиеся GameObject’ статус в сцене, и они могут быть контролируемыми через GameObject’s скриптирование API.

Типичный GameObject в Inspector. В данном случае это направленный свет. Свойства состояния Scene выделены красным цветом.
Типичный GameObject в Inspector. В данном случае это направленный свет. Свойства состояния Scene выделены красным цветом.

Активный статус

Активный статус GameObject
Активный статус GameObject

GameObjects активны по умолчанию, но могут быть деактивированы, что отключает все компоненты, подключенные к GameObject. Это обычно означает, что он станет невидимым и не получит никаких обычных обратных вызовов или событий, таких как Update или FixedUpdate.

Статус активного GameObject представлен флажком слева от имени GameObject. Вы можете управлять этим с помощью GameObject.SetActive.

Вы также можете использовать GameObject.activeSelf чтобы прочитать текущее активное состояние GameObject. Используйте GameObject.activeInHierarchy для чтения, действительно ли GameObject активен в сцене. GameObject.activeInHierarchy нужны, потому что фактическая активность GameObject определяется его собственным активным состоянием и активным состоянием всех его родителей. Если хотя бы один из родителей неактивен, объект неактивен, каким бы ни было его собственное значение.

Статическое состояние

Статическое состояние GameObject
Статическое состояние GameObject

Некоторые системы Unity — Global Illumination, Occlusion, Batching, Navigation и Reflection Probes — опираются на статический статус GameObject. Вы можете задать, какие из систем Unity будут считать этот GameObject static путем использования GameObjectUtility.SetStaticEditorFlags. Для получения дополнительной информации см. Статическое GameObjects.

Метки и слои

Поля Тег и Слой GameObject
Поля Тег и Слой GameObject

Метки обеспечивать способ маркировки и идентификации типов GameObject в вашей сцене и Слои предусматривают аналогичный, но отличающийся способ включения или исключения групп GameObjects от некоторых встроенных действий, таких как рендеринг или физика столкновения.

Для получения более подробной информации о том, как использовать метки и слои в редакторе, обратитесь к главным страницам руководства пользователя для Метки и Слои.

Вы можете изменять значения тегов и слоев с помощью скрипта, используя свойства GameObject.tag и GameObject.layer. Вы также можете эффективно проверить тег GameObject, используя метод CompareTag, который включает проверку наличия тега и не вызывает выделения памяти.

Добавление и удаление компонентов

Вы можете добавлять или удалять компоненты во время выполнения, что может быть полезно для процедурного создания GameObjects или изменения поведения GameObject. Обратите внимание, что вы также можете добавлять компоненты скриптов ,enable, or ,disable, и некоторые типы встроенных компонентов через скрипт без их уничтожения.

Лучший способ добавить компонент во время выполнения — это использовать AddComponent<Type>, указав тип компонента в квадратных скобках, как показано на рисунке. Чтобы удалить компонент, вы должны использовать метод Object.Destroy на самом компоненте.

Компоненты доступа

Самый простой случай — это когда скрипт на GameObject нуждается в доступе к другому Компоненту, прикрепленному к тому же GameObject (помните, что другие скрипты, прикрепленные к GameObject, тоже сами являются Компонентами). Для этого первым шагом является получение ссылки на экземпляр Компонента, с которым вы хотите работать. Это делается с помощью метода GetComponent. Обычно вы хотите назначить объект Компонент переменной, что делается с помощью следующего кода. В этом примере скрипт получает ссылку на компонент Rigidbody на том же GameObject:

void Start ()
{
    Rigidbody rb = GetComponent<Rigidbody>();
}

Как только у вас появится ссылка на экземпляр Компонента, вы можете установить значения его свойств так же, как в Inspector:

void Start ()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    // Change the mass of the object's Rigidbody.
    rb.mass = 10f;
}

Вы также можете вызывать методы в ссылке Компонент, например:

void Start ()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    // Add a force to the Rigidbody.
    rb.AddForce(Vector3.up * 10f);
}

Примечание: к одному GameObject можно прикрепить несколько собственных скриптов. Если из одного скрипта нужно обратиться к другому, используйте обычный GetComponent и укажите имя класса скрипта (или имя файла) в качестве нужного типа компонента.

Если вы попытаетесь извлечь тип компонента, который не был добавлен в GameObject, то GetComponent вернёт null. Вы получите ошибку null reference во время выполнения, если попытаетесь изменить какие-либо значения на нулевом объекте.

Компоненты доступа на других GameObjects

Хотя они иногда работают в изоляции, обычно скрипты отслеживают другие GameObjects, или чаще, компоненты на других GameObjects. Например, в кулинарной игре шеф-повару может понадобиться знать местоположение плиты. Unity предоставляет различные способы получения других объектов, каждый из которых подходит для определенных ситуаций.

Ссылка на GameObjects с переменными в Inspector

Самый простой способ найти связанный GameObject — добавить в скрипт открытую переменную типа GameObject:

public class Chef : MonoBehaviour
{
    public GameObject stove;

    // Other variables and functions...
}

Эта переменная будет видна в Inspector, как поле GameObject.

Теперь вы можете перетащить объект из сцены или панели Hierarchy на эту переменную, чтобы назначить его.

Функция GetComponent и переменные доступа Компонента доступны для этого объекта, как и для любого другого, так что вы можете использовать код, подобный следующему:

public class Chef : MonoBehaviour {

    public GameObject stove;

    void Start() {
        // Start the chef 2 units in front of the stove.
        transform.position = stove.transform.position + Vector3.forward * 2f;
    }
}

Кроме того, если вы объявите в скрипте открытую переменную типа компонента, на неё можно перетащить любой GameObject с этим компонентом. Так вы получите доступ непосредственно к компоненту, а не к самому GameObject.

public Transform playerTransform;

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

Найти ребенка GameObjects

Иногда игра Scene использует несколько GameObjects одного типа, таких как коллекционные предметы, точки пути и препятствия. Они могут нуждаться в отслеживании с помощью конкретного скрипта, который контролирует или реагирует на них (например, все точки пути могут быть доступны для скрипта поиска пути). Использование переменных для связывания этих GameObjects возможно, но это делает процесс разработки утомительным, если каждая новая точка пути должна перетаскиваться к переменной в сценарии. Аналогичным образом, если точка пути удаляется, то это неудобство, когда нужно удалить ссылку переменной на отсутствующую GameObject. В таких случаях зачастую лучше управлять набором GameObjects, делая их всеми дочерними элементами одного родительского GameObject. Дочерний GameObjects может быть получен с помощью родительского компонента Transform (потому что все GameObjects имплицитно имеют Transform):

using UnityEngine;

public class WaypointManager : MonoBehaviour {
    public Transform[] waypoints;

    void Start()
    {
        waypoints = new Transform[transform.childCount];
        int i = 0;

        foreach (Transform t in transform)
        {
            waypoints[i++] = t;
        }
    }
}

Вы также можете найти конкретный дочерний объект по имени, используя метод Transform.Find:

transform.Find("Frying Pan");

Это может быть полезно, когда у GameObject есть дочерний объект GameObject, который может быть добавлен и удален во время игры. Хорошим примером этого является инструмент или принадлежность, которую можно поднять и опустить во время игры.

Отправка и распространение сообщений

Во время редактирования проекта вы можете установить ссылки между GameObjects в Inspector. Однако иногда невозможно установить их заранее (например, найти ближайший объект к персонажу в вашей игре, или сделать ссылки на GameObjects, которые были инстанцированы после загрузки Scene). В этих случаях вы можете найти ссылки и отправить сообщения между GameObjects во время выполнения.

BroadcastMessage позволяет отправить вызов именованному методу, не указывая конкретно, где этот метод должен быть реализован. Вы можете использовать его для вызова именованного метода на каждом MonoBehaviour на конкретном GameObject или на любом из его дочерей. Вы можете по желанию выбрать, чтобы требовать наличия хотя бы одного получателя (иначе возникает ошибка).

SendMessage немного более специфичен, и отправляет вызов только именованному методу на самом GameObject, а не его дочерним методам.

SendMessageUpwards аналогичен, но отправляет вызов в названный метод на GameObject и всеми его родителей.

Найти GameObjects по имени или метке

Всегда можно найти GameObjects в любом месте иерархии Scene, если у вас есть информация, позволяющая их идентифицировать. Отдельные объекты можно получить по имени с помощью функции GameObject.Find:

GameObject player;

void Start()
{
    player = GameObject.Find("MainHeroCharacter");
}

Объект или коллекцию объектов также можно найти по их метке с помощью методов GameObject.FindWithTag и GameObject.FindGameObjectsWithTag.

Например, в кулинарной игре с одним персонажем-шеф-поваром и несколькими плитами на кухне (каждая из которых имеет метку «Плита»):

GameObject chef;
GameObject[] stoves;

void Start()
{
    chef = GameObject.FindWithTag("Chef");
    stoves = GameObject.FindGameObjectsWithTag("Stove");
}

Создание и уничтожение GameObjects

Вы можете создавать и уничтожать GameObjects во время выполнения проекта. В Unity GameObject может быть создан с помощью метода Instantiate, который создает новую копию существующего объекта.

Полное описание и примеры создания экземпляра GameObjects см. в Создание экземпляра Префабы во время выполнения.

Метод Destroy уничтожает объект после завершения обновления кадра или, по желанию, после короткой задержки:

void OnCollisionEnter(Collision otherObj) {
    if (otherObj.gameObject.tag == "Garbage can") {
        Destroy(gameObject, 0.5f);
    }
}

Обратите внимание, что функция Destroy может уничтожать отдельные компоненты и не влиять на сам GameObject. Частая ошибка — написать this и предположить, что она уничтожает GameObject, к которому прикреплен скрипт:

Destroy(this);

this представляет скрипт, а не GameObject. На самом деле это просто уничтожит компонент скрипт, который вызывает его, и оставит GameObject нетронутым, но с удаленным компонентом скрипт.

Примитивы

Класс GameObject предлагает программные аналоги пунктов меню GameObject в Unity, позволяющих создавать примитивные объекты.

Чтобы создать экземпляры Unityвстроенные примитивы, использование GameObject.CreatePrimitive, который создает экземпляр примитива указанного типа. Доступны следующие типы примитивов: Sphere, Capsule, Cylinder, Cube, Plane и Quad.

Примитивные формы доступны в Unitys GameObject menu
Примитивные формы, доступные в меню GameObject редактора Unity

Дополнительные ресурсы