Неожиданное исключение на ровном месте

Намедни столкнулся с неожиданным (по крайней мере для меня) исключением на банальном куске кода в Unity. Если убрать все лишнее, то получится примерно вот такой скрипт:

Вышепреведенный код отрабатывал без ошибок, если на игровом объекте висел компонент CanvasGroup . А если этого компонента нет, то код генерирует исключение:

MissingComponentException: There is no ‘CanvasGroup’ attached to the «Button» game object, but a script is trying to access it.
You probably need to add a CanvasGroup to the game object «Button». Or your script needs to check if the component is attached before using it.
TestScript.Start () (at Assets/TestScript.cs:10)

По задумке, само собой, не ожидалось никакого исключения. Какое-то время потребовалось, чтобы понять, почему генерируется это исключение. Я, конечно, был в курсе, что Unity переопределяет оператор сравнения и что использовать операторы ?.  и  ??  с Unity.Object  и его наследников не следует. Но почему-то мне казалось, что переопределенный оператор на что-то влияет, только если мы имее дело с уничтоженным объектом. В моем же коде, по идее, этого не должно было быть. И потому это исключение оказалось неожиданным. Логично было бы предположить, что вместо  MissingComponentException будет генерироваться исключение  NullPointerException . Но, как вы уже поняли, этого не происходит. Согласно документации, метод  GetComponent :

Returns the component of Type type if the game object has one attached, null if it doesn’t.

Этот метод должен вернуть ссылку на компонент или  null , если компонент не найден. А далее приводится пример:

который «подтверждает» ранее описанное поведение. Но если бы это была бы правда, то мой код бы не генерировал исключение. А он генерирует. Дело в том, что метод  GetComponent возвращает ссылку на управляемый компонент, даже если компонент не найден. Иными словами, если запрашиваемый компонент не найден, то все равно возвращается ссылка на управляемый компонент, который не ссылается на настоящий C++ компонент и переопределенный оператор сравнения с  null  не срабатывает.  Создается ощущение, что вернулся  null . Это легко подтвердить, например, таким кодом:

В результате выполнения этого кода мы увидим:

UnityEngine.CanvasGroup
UnityEngine.Debug:Log(Object)
TestScript:Start() (at Assets/TestScript.cs:9)

Также стоит отметить, что, если сбилдить приложение, то тестовый код выполнится без ошибок, а ненайденный компонент будет добавлен. Происходит это потому, что в run-time  GetComponent будет возвращаться настоящий  null , и все выполнится, как и задумывалось. Т.е. подмена возвращаемого значения работает только в редакторе Unity. Само собой, не стоит использовать операторы  ?.  и  ??  с  Unity.Object  и его наследниками в реальном коде.

Unity для новичков. Простая камера от третьего лица. Часть 1

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

Читать →

Unity для новичков. Делаем зомби шутер. Часть 4

Введение в разработку на игровом движке Unity — практикум. Часть 4.
Это последний видеоурок из серии — завершаем проект. Улучшаем управление персонажем, добавляя движение камеры по вертикали. Создаем точки респауна зомби и генерируем их с уменьшением интервала. Заканчиваем UI: реализуем подсчет очков, используем делегат (Delegates) для обновления интерфейса, скрываем и фиксируем курсор мыши. Делаем билд игры.

Читать →

Unity для новичков. Делаем зомби шутер. Часть 3

Введение в разработку на игровом движке Unity — практикум. Часть 3.
Простое управление персонажем на основе компонента Character Controller. Работа с устройствами ввода. Что такое класс Input и оси управления и их использование для перемещения, поворота персонажа и прочих элементов управления.

Что такое Raycast и его использование на примере стрельбы. Использование информации о точке пересечения Raycast с объектом для добавления декалей и применения физической силы к игровым объектам. Добавление звуков в игру. Анимации, атака и смерть зомби.
Читать →

Unity для новичков. Делаем зомби шутер. Часть 2

Введение в разработку на игровом движке Unity — практикум. Часть 2.
Введение в работу с пользовательским интерфейсом в Unity. Как добавлять и манипулировать элементами пользовательского интерфейса, такими, как текст, изображение и кнопки. Что такое точки привязки (якоря) и точки начала координат (Pivot) элементов UI. Переход между сценами и выход из приложения по нажатию на графические кнопки.
Затрагивается работа с навигацией (поиском пути) в Unity. Запекание навигации, добавление и настройка агента.
И в заключение второго урока мы напишем небольшой скрипт поведения врагов и познакомимся с корутинами (Coroutine).
Читать →

Unity для новичков. Делаем зомби шутер. Часть 1

Введение в разработку на игровом движке Unity — практикум. Рассматривается как создать проект. Навигация в редакторе Unity и управление камерой основного вьюпорта. Как импортировать сторонние ресурсы в проект. Настройка персонажа гуманоидного типа для анимации. Базовые возможности системы анимации Mecanim. Даны примеры использования дерева смешивания и анимации по маске. Данное видео является вступительным в серии по созданию простого зомби-шутера.

Читать →

Лицевые анимации игровых персонажей

Рано или поздно каждый разработчик игр сталкивается с задачей кастомизации внешности персонажа и/или лицевыми анимациями. Согласитесь, современная игра в которой игровые персонажи говорят с закрытым ртом будет выглядеть довольно странно. И зачастую это ставит в ступор, ввиду того, что информации на данную тему очень мало, а в русском сегменте чуть меньше, чем нет совсем. Хотя, правильнее сказать, информация то есть, но совсем в другом направлении, не касательно разработки игр. Давайте рассмотрим как можно реализовать лицевые анимации для игры на движке Unity.

Читать →

Как сделать игру на Unity. Урок 8: Физика. Применение силы

В уроке рассмотрена настройка физики в проекте. А так же:

  • Что такое физический материал и их настройка.
  • Основные параметры компонента Rigidbody.
  • Применение физических сил к игровым объектам.

Читать →

Как сделать игру на Unity. Урок 7: Звук в игре

Урок о добавлении звука в игру. В видео рассмотрен импорт звука и правильная настройка для сохранения баланса между производительностью и затратами памяти. Показано использование основных компонентов, работающих с аудио. А также показано, как включать тот или иной звук по необходимости, на примере изменения звука шагов в зависимости от поверхности.
Читать →