Как проверить столкновение с объектом по его тегу?
Есть объект, состоящий из двух частей, у каждой свой тег. При соприкосновении с первой частью объект будет уничтожаться, а при соприкосновении с другой ничего не будет происходить. Как такое реализовать?
- Вопрос задан 03 нояб. 2022
- 151 просмотр
Комментировать
Решения вопроса 1
Sannyprrod @Sannyprrod
private void OnCollisionEnter(Collision collision) < if (collision.gameObject.CompareTag("FirstPart")) < Destroy(gameObject); >> Для 2D: private void OnCollisionEnter2D(Collision2D col) < if (col.gameObject.CompareTag("FirstPart")) < Destroy(gameObject); >>
+- вот так, но лучше, по возможности, искать решения без использования тегов, теги в основном bad practice
Ответ написан 03 нояб. 2022
Нравится 2 2 комментария
Не получается проверить столкновение объектов в Unity 2D
Делаю 2д игру в которой есть игрок (ракета которая стреляет) и враги (пришельцы которые летят вниз). Мне нужно проверить столкновение пули с врагом, но у меня никак не получается это сделать.
private void OnTriggerEnter2D(Collider2D other) < if (other.gameObject.layer == LayerMask.NameToLayer("Laser")) < this.gameObject.SetActive(false); >> >
это код в скрипте врага Ниже инспектор пули.
Отслеживать
TrueTruffle
задан 14 фев в 6:57
TrueTruffle TrueTruffle
45 6 6 бронзовых знаков
Приведите больше информации насчет пули. Будет хорошо если вы приведете скрин инспектора пули.
14 фев в 8:09
@nchistov, показал
14 фев в 11:42
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
В чём проблема, раз уж на пуле есть коллайдер, сделать проверку не по слою объекта, а по его тегу:
private void OnTriggerEnter2D(Collider2D other) < if (other.CompareTag("Laser")) < gameObject.SetActive(false); >> >
Только не забудь пуле добавить тег Laser
Отслеживать
ответ дан 14 фев в 13:02
Nick Shakhrai Nick Shakhrai
123 8 8 бронзовых знаков
Вообще не работает, пули просто насквозь пролетают. Тег добавил, название совпадает с проверяемым. У врага есть коллайдер.
Как проверить столкновение в в unity
void OnEnterCollider(Collider Coll)
if(coll.tag==»тег твоего объекта»)то что нужно сделать;
за грамотность синтаксиса не отвечаю)
Сообщение отредактировал Vicka — Суббота, 16 Апреля 2016, 23:12
почти ветеран
Сейчас нет на сайте
Цитата Vicka ( )
void OnEnterCollider(Collider C oll)<
<>
if( c oll.tag==»тег твоего объекта»)то что нужно сделать;
Должно быть
OnCollisionEnter (Collision coll)
Сообщение отредактировал URGINSAN — Суббота, 16 Апреля 2016, 23:45
был не раз
Сейчас нет на сайте
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
Цитата Robinzon787 ( )
а именно когда столкновение например было прервано уничтожением объекта(того что вошел в триггер
заслуженный участник
Сейчас нет на сайте
заслуженный участник
Сейчас нет на сайте
Construct’орщик
Сейчас нет на сайте
заслуженный участник
Сейчас нет на сайте
Цитата Robinzon787 ( )
но бывают случаи когда этот объект может быть уничтожен
Разработка компьютерных игр. С чего начать? Это просто! С нуля до разработчика игр: как начать создавать свою игру. Заказать создание игры.
Как использовать функции столкновений в Unity: OnCollisionEnter/Stay/Exit, OnTriggerEnter…
Столкновения (Collisions) играют важную роль в компьютерных играх. Это, пожалуй, не конкретная механика, а объемный пласт взаимодействия между игровыми объектами.
В этой статье (потом, возможно, серии статей) мы разберем, как работать со столкновениями в Unity, как ловить и обрабатывать их в коде, глубже погрузимся в тему и постараемся ответить на часто возникающие вопросы.
Предполагается, что вы уже знаете Unity и С# на базовом уровне: посмотрели один-два туториальчика, почитали парочку статей, успели потыкать в движке что-то самостоятельно и хотите продолжать развиваться
Как работает система столкновений? Что такое коллайдеры?
Система столкновений Unity работает за счет коллайдеров (Colliders).
Коллайдер — это компонент, который представляет собой невидимые «границы» объекта.
Часто они совпадают с формой самого объекта (как в реальном мире), хотя это и не обязательно.
Unity поддерживает разнообразные формы коллайдеров:
- BoxCollider — форма прямоугольного параллелепипеда
- SphereCollider — сфера
- CapsuleCollider — капсула (математически, сфероид или эллипсоид вращения)
- MeshCollider — кастомная форма 3Д-меша, соответствующая форме самого меша.
- BoxCollider2D — прямоугольник
- CircleCollider2D — круг
- PolygonCollider2D — кастомная форма 2Д-спрайта, повторяющая форму самого спрайта.
- .
Повторюсь, коллайдеры задают границы объектов, которые используются при расчете физики. Например:
Кубик лежит на столе: и куб, и стол имеют границы, поэтому не проходят сквозь друг друга.
В героя попала шальная пуля: мы зафиксируем это и уменьшим его здоровье.
Герой бежит и упирается в стену: он не может пробежать сквозь стену, потому что они оба имеют границы.
Триггеры
Триггеры — это те же коллайдеры. Серьезно, всего одна галочка в любом компоненте коллайдера превращает его в триггер!
Но триггеры «физически прозрачны». Другими словами, объекты, помеченные как триггеры*, не являются твердыми телами и пропускают любое другое тело сквозь себя.
Триггеры в основном используют как некие зоны, или области, попадание в которые влечет за собой какие-то последствия. Например:
Комната в ядовитым газом — это один большой триггер: герой проходит сквозь него без физического взаимодействия, но все время, пока герой внутри, он получает пассивный урон от яда.
Зона видимости врага — тоже триггер: когда герой находится в этой зоне, враг видит его и стреляет по нему.
Зона открытия двери — тоже может быть триггером: расположим эту зону рядом с дверью. Если игрок нажимает кнопку E находясь внутри этой зоны (т.е. достаточно близко к двери), то она открывается, иначе — нет.
Обработка столкновений
Самое интересное и важное: как правильно из кода узнать, что столкновение произошло и обработать это?
Для этого разработчики Unity подкатили нам целую набор функций. Предлагаю на практике подробно рассмотреть как работает одна из них, а потом на ее примере обсудим другие.
Итак, перед вами сцена с большой платформой, кубиком и шариком (а также небольшим освещением). Давайте сделаем так, чтобы при падении шарика на кубик последний уничтожался.
Давайте повесим коллайдеры на объекты: на шарик — SphereCollider , на кубик — BoxCollider . Помимо этого, обоим объектам добавим компонент Rigidbody .
Скорее всего, вы уже знаете, что Rigidbody — это компонент, который добавляет объектом физику. Именно благодаря ему шарик будет падать, а при соприкосновении с кубиком — отскочит от него.
Создадим скрипт Ball.cs в папке Scripts. Сразу повесим его на шарик, чтобы потом не забыть. В скрипт нужно добавить следующий код:
public class Ball : MonoBehaviour < private void OnCollisionEnter(Collision collision) < print("Collision detected"); >>
Функция OnCollisionEnter будет вызвана автоматически, когда шарик соприкоснется с чем-либо. Самим где-либо вызывать ее не надо.
Попробуйте запустить код и убедитесь, что в консоль выводится нужная фраза при столкновении с кубиком.
Единственный аргумент collision хранит информацию о столкновении. В частности он содержит переменную gameObject , в которой хранится объект, с которым произошло столкновение.
Попробуйте заменить print(«Collision detected») на print(collision.gameObject) и увидите, что при столкновении в консоль выводится информация о нашем кубике:
Теперь вместо принта будем удалять этот самый кубик:
private void OnCollisionEnter(Collision collision)
Функция Destroy() позволяет уничтожить какой-либо объект. Первым аргументом она принимает сам объект (в нашем случае кубик), а вторым — опционально — через сколько секунд должно произойти уничтожение.
Сохраните скрипт и запустите игру, чтобы увидеть, как шарик уничтожает сначала кубик, а затем — неожиданно — и пол! Да, ведь пол — это такой же объект, который имеет коллайдер (можете проверить:)
Как сделать чтобы пол не удалялся?
Самым правильным будет повесить на пол специальный тег, по которому его можно будет отличить от других объектов. Для этого выберите пол, создайте новый тег в инспекторе, нажав «Add Tag. » и назовите его Floor . После этого вновь выберите пол и прикрепите к нему этот тег (он появится в списке).
Теперь добавим в код проверку, чтобы уничтожать только те объекты, которые НЕ имеют тега «Floor»:
private void OnCollisionEnter(Collision collision) < if (collision.gameObject.tag != "Floor") < Destroy(collision.gameObject); >>
(Ну, или можно было все оставить как есть и сказать, что это не баг, а фича)
Перейдем к другим функциям
Не закрывайте проект. Замените написанную функцию на такую:
private void OnCollisionStay(Collision collision)
Запустив проект, вы увидите, что строка выводится в консоль каждый божий кадр.
Функция OnCollisionStay срабатывает каждый* кадр, когда объекты соприкасаются хоть чуть-чуть.
А функция OnCollisionExit срабатывает всего один кадр — когда касание прекратилось.
* На самом деле, не совсем: это физическая функция и она срабатывает каждый физический кадр. Детское объяснение в одну строку: Unity обрабатывает физику отдельно от не-физики: физика обрабатывается только в «физических кадрах», коими являются не все.
Опять к триггерам
Обсудим теперь триггеры. Вы можете попробовать отметить галочку «Is Trigger» в компоненте SphereCollider у шара. Запустив игру вы моментально поймете, что такое триггеры, если у вас пока не сложилось представление:)
Перейдите теперь на другую сцену, TriggersLesson, в папке «Scenes». Запустив игру вы увидите, что играете за капсулу, превращать которую в нормального героя мне было лень:)
Давайте сделаем так, чтобы при входе в горящую зону наш герой увеличивался, при нахождении в ней — мигал, а при выходе — вновь уменьшался.
Помним, что эта зона — триггер (можете в этом убедиться, в компоненте коллайдере отмечена галочка IsTrigger), а потому будем использовать триггерные функции. Найдем в папке Scripts файл Player.cs . Он уже содержит некоторые функции, отвечающие за перемещение игрока. Добавьте в конце еще несколько функций:
private void OnTriggerEnter(Collider other)
Обратите внимание, что триггерные функции НЕ принимают в качестве аргумента объект типа Collision, т.е. информацию о столкновении, так как самого столкновения не было. Вместо этого они просто хранят ссылку на компонент-коллайдер того объекта, с которым столкнулись. В нашем случае, так как скрипт висит на герое, переменная other ссылаться на саму зону.
Мы проверяем, является ли она нашим триггером и увеличиваем объект.
Если оставить все как есть, то в круг можно несколько раз входить-выходить и достигнуть гигантских размеров. Давайте это исправим:)
private void OnTriggerExit(Collider other) < if (other.gameObject.tag == "FireZone") transform.localScale /= 2; >
Похожая функция: проверяем, вошли ли мы действительно в зону и уменьшаем игрока.
private void OnTriggerStay(Collider other) < if (other.gameObject.tag == "FireZone") < Color color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)); GetComponent().material.color = color; > >
Эта функция создаст разноцветное случайное мерцание. Мы просто меняем цвет материала, примененного к мешу. Для этого мы обращаемся к компоненту MeshRenderer.
Кстати, каждый кадр использовать GetComponent() — плохая практика. Это сильно бьет по производительности. Поэтому компоненты стоит кэшировать. Я уже сделал это в 9-й и 14-й строках: объявил переменную и инициализировал ее в функции Awake. Теперь просто замените вызов GetComponent() на переменную _mesh .
Кстати, закэшировал я и компонент Rigidbody , который мне тоже нужен каждый кадр для перемещения персонажа.
Мне кажется, эта статья итак уже выходит довольно длинной, поэтому я опишу как использовать 2Д-версии функций столкновения в следующей статье (если она будет. )
ДЗ:
В качестве практики предлагаю вам поработать с обеими сценами. Например, можно сделать следующее:
- На первой сцене вместо скрипта для шарика напишите скрипт для кубика, который будет изменять цвет шарика на, скажем, зеленый, когда коснется его. Возьмите код изменения цвета из конца урока и убедитесь, что кубик случайно не красит еще и пол!
- На второй сцене выньте камеру из персонажа в иерархии, размножьте их на сцене и полностью перепишите их скрипт, чтобы они бегали в случайные стороны. А потом создайте скрипт для огненной зоны, в котором реализуйте все, что мы делали в этом уроке. Теперь у вас по карте бегает куча недоделанных миньонов, каждый из которых вырастает и мелькает, когда попадает в огненную зону!
На этом все!
P.S. Это моя первая статья. Буду рад увидеть комментарии с конструктивной критикой. Также готов ответить на вопросы в комментариях.
P.P.S. Кто-нибудь знает, куда люди обычно прикрепляют ссылки, такие как у меня здесь — на папку с игрой? А то на гугл диске не очень хочется место занимать, а онлайн-файлообменники позволяют расположить файлы только на конкретные срок.