Создание игр. Столкновение объектов в Unity. Часть 4
Содержание
Продолжаем изучать создание игр и разберемся как отловить столкновение объектов в Unity программно. Напомню, что в предыдущей статье Создание игр с нуля на Unity. Часть 3. мы рассмотрели как получить доступ к объекту в коде, изменили его параметры, добавили физический материал на объект, добавили музыку. Если вы пропустили начало данного цикла статей по созданию игр на Unity – вот первая статья: Создаем игру. Unity. Разбираемся с нуля. А теперь приступим к продолжению нашего путешествия.
Collision detection – столкновение объектов.
Столкновение объектов
Как мы помним, в предыдущей статье мы научили наши объекты чувствовать друг друга и реагировать на объекты в игровом мире. Очень часто возникает надобность отловить в коде момент когда два объекта соприкасаются, сталкиваются друг с другом: пуля убивает человека, автомобиль врезается в другой и ему надо нанести урон, птица попадает в двигатель самолета.
Итак, вы можете добавить новый объект на сцену, добавим ему твердотелость, как то было в предыдущей статье. Либо же использовать с предыдущего примера. Я возьму предыдущий объект. Теперь создадим новый скрипт и поместим его на данный объект. Как это делать мы уже помним с вами. Назову его CollisionScript.
Как отловить столкновение объектов
Открыв данный скрипт, вы вспомните 2 метода, которые мы с вами рассматривали. Давайте добавим новый метод, который называется OnCollisionEnter. Не поленитесь найти его в документации и почитать. Там сказано следующее:
OnCollisionEnter вызывается, когда этот collider/rigidbody начал соприкосновение с другим rigidbody/collider.
Своим параметром он принимает объект Collision collision. В данном объекте хранится информация о точках соприкосновения.
Событие OnCollisionEnter
Давайте посмотрим пример.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CollisionScript : MonoBehaviour { // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void OnCollisionEnter(Collision collision) { Debug.Log("I have touched it! I've touched " + collision.gameObject.name); } }
Запустите его, объект начнет падать и при соприкосновении вашего объекта с поверхностью в консоли должно появиться соответствующее сообщение.
Давайте теперь перейдем к нашему объекту сферы, который мы роняемо на поверхность. Перейдя в свойства можно увидеть Sphere Collider – это невидимый объект, который касается. Поясню немного: когда у нас происходит столкновение – определяется не сам видимый объект, а его collider. Попробуйте изменить его параметры что бы ощутить это на своей шкуре. Например я здесь увеличил радиус. Изменяя его вы будете видеть это визуально на сцене. Таким образом наш объект соприкоснется с поверхностью фактически не касаясь ее. Запустите вашу игру и сами удивитесь.
Так же моно поэкспериментировать удалив данный коллайдер и добавив другой, например куба. Это будет нечто.
Событие OnTriggerEnter
В примере выше мы отлавливали событие, когда два твердых тела соприкасаются друг с другом. Здесь же рассмотрим немного другой пример. Предположим, что мы хотим отлавливать событие, когда один объект находится в определенном месте. К примеру, это может быть портал, в который входит игрок, панель ускорения, на которую наезжает автомобиль, как в старых гоночка Crash. Грубо говоря, мы определяем столкновение, но не с твердым телом. Когда наш объект проходит через определенный участок.
Давайте создадим нашу сцену для реализации примера. Я поставил новый объект – куб. Он будет проходить у нас через портал. Создал портал – использовал 2 куба, сделал из них два бруска и наклонил под углом. Поместил их на пустой объект, который назвал Portal. Последний штрих – на объекте портал добавил компонент Box Collider. Настроил его так, что бы он находился внутри нашего портала. Именно по нему мы будем определять когда игрок проходит наш портал. Вот мой пример.
Не забудьте нажать чекбокс Is Trigger. В моем примере коллайдер выходит за приделы портала, но на данном этапе это не существенно. Наша задача сейчас определить когда объект проходит определенный участок в игре.
Создадим новый скрипт TriggerScript и поместим его на наш объект, который будет проходить через портал. В моем примере это куб с именем Block. Откроем наш скрипт и добавим долгожданный метод OnTriggerEnter. Так же можем добавить еще похожий OnTriggerExit. Если первый метод срабатывает когда мы входим в нашу область, то второй, соответственно – когда выходим. Не забудьте добавить нашему кубу свойство Rigid Body. Поместим в эти методы следующий код:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TriggerScript : MonoBehaviour { // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } void OnTriggerEnter(Collider other) { Debug.Log("Entered"); } void OnTriggerExit(Collider other) { Debug.Log("Exit"); } }
Запустите игру. Так как мы на данном этапе еще не можем управлять нашим объектом – откройте вкладку Scene в процессе игры и перемещайте наш куб в портал. Либо же изменяйте параметры в инспекторе. В момент когда он входит и выходит сквозь него в консоли вы увидите сообщение в консоле.
Вот пример с видео, в консоли вы можете увидеть моменты когда куб проходит сквозь портал
Создание игр на Unity – Prefabs. Что такое префабы.
Давайте теперь разберемся что такое префабы (Prefabs), зачем они нужны и как их использовать. Часто возникает задача поместить много объектов на сцену. И это, в принципе, реализовать не сложно. Можно просто скопировать объект несколько раз. Но магия нужна будет в случае, если вы захотите каким-то образом изменить объект. В данном случае изменяя один объект, остальные будут нетронутыми. Наша задача изменить все одним махом. На помощь приходят префабы (Prefabs). Глянем что написано в документации.
Префаб – определение
Префабы – это особый тип ассетов, позволяющий хранить весь GameObject со всеми компонентами и значениями свойств. Префаб выступает в роли шаблона для создания экземпляров хранимого объекта в сцене. Любые изменения в префабе немедленно отражаются и на всех его экземплярах, при этом вы можете переопределять компоненты и настройки для каждого экземпляра в отдельности.
Пример префаба
Что бы разобраться более близко с префабами – давайте перейдем к примеру. Это позволит нам на своей шкуре ощутить силу префабов. Для этого создадим очередной странный объект: у меня он будет состоять из двух объектов Capsule и куба, преобразованного в параллелепипед. Поместим это все чудо на пустой объект. Я его назвал Platform и у меня все это выглядит следующим образом:
Далее создадим пару материалов. Один из них будет для верхней части платформы, а другой – для нижней, наверное это колеса, я не знаю. Настройте их на свой вкус. Думаю, вы помните как это делать. Если нет – в предыдущих частях есть описание этого процесса. Я просто поменял цвета у материалов со стандартного.
После всего этого переместим наши материалы на соответствующие части нашего объекта и получим наш красивенький, странноватый и разукрашенный объект, который я назвал Platform.
Далее простым движением перенесем наш объект в папочку Assets, таким образом создадим новый Prefab.
Теперь сделаем следующее: скопируем объект Platform несколько раз. После этого зайдите в свойство одного из них и попробуйте изменять свойства. Вы должны заметить, что свойства применяются только к текущему объекту. А теперь приступим к магии префаба – зайдите в наш созданный префаб и поменяйте свойства каких-то компонентов. Я, например, изменил длину моих псевдо-колес. Вернувшись обратно на сцену вы заметите изменения на всех объектах этого префаба.
Вот что получилось в итоге:
Естественно префабы очень удобно использовать для очень сложных объектов. На этом мы закончим базовое ознакомление с префабами.