Функции событий столкновений: OnCollisionEnter, OnCollisionEnter2D, OnCollisionStay, OnTriggerEnter
Такие функции как OnCollisionEnter, OnTriggerEnter, OnCollisionStay и так далее часто не вызываются. Это смущает многих новичков, которые ввиду своих неглубоких знаний в данном вопросе не могут понять, что они делают не так.
Не будем также забывать, что эти функции разделены для триггеров и не-триггеров, для 2D и 3D, то есть их много и у каждой свои особенности.
Этот пост содержит в себе ответы на такие частые вопросы, как:
- для чего предназначены эти функции;
- как они работают;
- как нужно настраивать объекты, что эти функции корректно работали;
- почему они не вызываются или вызываются с ошибками
Ответы (1 шт):
Список функций:
В первую очередь перечислим все подобные функции. Всего их 12:
| События | Collider | Trigger |
|---|---|---|
| Enter | OnCollisionEnter(Collision) | OnTriggerEnter(Collider) |
| Stay | OnCollisionStay(Collision) | OnTriggerStay(Collider) |
| Exit | OnCollisionExit(Collision) | OnTriggerExit(Collider) |
Те же функции но для 2D объектов:
| События | Collider | Trigger |
|---|---|---|
| Enter | OnCollisionEnter2D(Collision) | OnTriggerEnter2D(Collider) |
| Stay | OnCollisionStay2D(Collision) | OnTriggerStay2D(Collider) |
| Exit | OnCollisionExit2D(Collision) | OnTriggerExit2D(Collider) |
! Все ссылки рабочие и направляют на страницу своей функции
О функциях OnCollision... и их 2D версиях
Из документации:
- OnCollisionEnter вызывается, когда этот collider/rigidbody начал соприкосновение с другим rigidbody/collider.
- OnCollisionStay вызывается один раз в кадр для каждого collider/rigidbody, который касается другого rigidbody/collider.
- OnCollisionExit вызывается, когда collider/rigidbody прекращает контакт с другим rigidbody/collider.
Все вышеперечисленные тезисы верны в том числе и для 2D версий функций.
Аргумент:
Все они принимают в качестве первого аргумента — Collision, НЕ Collider. Класс Collision содержит информацию о точках соприкосновения, скорости воздействия и т.д.
Требования:
- Оба объекта должны иметь на себе компонент Collider.
- У обоих объектов в компоненте Collider должно быть ОТКЛЮЧЕНО свойство
isTrigger. - Хотя бы один из двух объектов должен иметь компонент Rigidbody.
- У объекта(-ов) с компонентом Rigidbody должно быть ОТКЛЮЧЕНО свойство
isKinematic.
Важно:
- События столкновений отправляются даже на неактивные компоненты.
- События столкновений НЕ отправляются на объекты с отключенным или временно неактивным компонентом Rigidbody.
О функциях-триггерах OnTrigger... и их 2D версиях
англ. trigger [ˈtrɪgə] - спусковой крючок, пусковой сигнал, триггер\
Collider с свойством триггера не является телесным и ни с кем не сталкивается (не взаимодействует).
Триггер используется как зона, которая способна реагировать на события входа/выхода/нахождения в ней чего-либо и запуска неких сценариев.
Из документации:
- OnTriggerEnter вызывается, когда Collider other входит в триггер.
- OnTriggerStay вызывается практически каждый кадр для каждого Collider other, которые соприкасаются с триггером.
- OnTriggerExit вызывается, когда Collider other перестает соприкасаться с триггером.
Все вышеперечисленные тезисы верны в том числе и для 2D версий функций.
Аргумент:
Все они принимают в качестве первого аргумента — Collider, то есть ссылку на компонент объекта, с которым произошло триггерное столкновение.
Требования:
- Оба объекта должны иметь на себе компонент Collider.
- РОВНО один (НЕ два) должен быть помечен как триггер (то есть свойство isTrigger должно быть равно true) в компоненте Collider.
-
- Хотя бы один из двух объектов должен иметь компонент Rigidbody.
Важно:
- Функции-триггеры вызываются в FixedUpdate после непосредственного входа в триггер/выхода из триггера и т.д., поэтому объекты, участвующие в столкновении, в момент вызова функции-триггера могут уже находиться не той позиции, где были в момент столкновения.
- Функции-триггеры не являются непосредственной частью столкновений, а лишь функцией MonoBehaviour'a.
- Функция OnTriggerStay зависит от физического таймера, поэтому нет необходимости вызывать ее каждый кадр — она может вызываться НЕ в каждом кадре.
Помните также о том, что если вы не используете аргументы, указываемые в функциях (Collision other, Collider collider...), вам следует их опустить: в таком случае ненужные расчеты не будут производиться.