Обробка зіткнень зі стандартною фізикою (2D)

Сторінка оновлюється :
Дата створення сторінки :

Середовище перевірки

Вікна
  • вікна 11
Редактор єдності
  • 2021.3.3f1
Пакет системи введення
  • 1.3.0

Передумови для цієї поради

Наступні настройки були зроблені заздалегідь як передумова для опису цієї поради.

Спочатку

Ця порада розміщує два об'єкти таким чином, щоб ви могли реалізувати поведінку, маніпулюючи одним об'єктом і використовуючи стандартну фізику Unity, щоб підштовхнути інший, коли він вступає в контакт з іншим.

До речі, більшість налаштувань збігаються з процедурою, описаною в попередній статті «Визначення зіткнення об'єктів один з одним (2D)».

Підготовка

Процедура тут практично така ж, як і попередні поради , тому давайте протікати плавно.

Після створення проекту підготуйте два спрайт-зображення, які будуть об'єктами, і додайте їх. Назви - "UnityTips" і "UnityTips_2" відповідно.

Додайте два файли зображень, перетягнувши їх у подання.

Додайте сценарій для переміщення лівого об'єкта за допомогою клавіатури. Ім'я Player сценарію .

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
  // 一定時間ごとに呼ばれます
  void FixedUpdate()
  {
    // キーボードの情報を取得
    var keyboard = Keyboard.current;

    // スプライトの移動処理
    if (keyboard.leftArrowKey.isPressed)
    {
      transform.Translate(-0.1f, 0, 0, Space.World);
    }
    if (keyboard.rightArrowKey.isPressed)
    {
      transform.Translate(0.1f, 0, 0, Space.World);
    }
    if (keyboard.upArrowKey.isPressed)
    {
      transform.Translate(0, 0.1f, 0, Space.World);
    }
    if (keyboard.downArrowKey.isPressed)
    {
      transform.Translate(0, -0.1f, 0, Space.World);
    }
  }
}

Прикріпіть до об'єкта, на якому потрібно запустити скрипт.

Запустіть гру і перевірте, чи працює вона з клавішами курсору на клавіатурі.

Нарешті, помістіть текстовий об'єкт для відображення стану виявлення зіткнень. Ім'я об'єкта TextState має вигляд .

Налаштування обробки зіткнень

Звідси ви можете налаштувати параметри, пов'язані з зіткненнями.

Спочатку виберіть об'єкт, який ви хочете перемістити, «UnityTips», і натисніть «Додати компонент» від інспектора. Виберіть зі Physics 2D списку. Physics є 3D-об'єктом, тому не помиляйтеся.

Physics 2DBox Collider 2D Виберіть із . Оскільки спрайт прямокутний, вибрано поле Box, але якщо він має форму кола, наприклад, виберіть інші фігури, наприклад Коло.

Минулого разу я хотів отримати інформацію лише про те, влучив я в нього чи ні, тому поставив галочку "Зробити тригер", але цього разу не буду. Це дозволяє обробляти зіткнення у фізиці.

Rigidbody 2D Потім додайте компоненти . Ви можете додати його з "Фізика 2D -> Rigidbody 2D". Rigidbody дає фізичну інформаціюCollider об'єкту, а також може визначати зіткнення з об'єктами, які мають .

Встановіть шкалу гравітації на 0, щоб запобігти вільному падінню нижче.

Аналогічно, додайте компонент до іншого об'єкта "UnityTips_2", щоб позначити Box Collider 2D звернення.

Крім того, на цей раз необхідно рухатися з силою суперника,Rigidbody 2D тому додайте . Шкала тяжіння повинна дорівнювати 0.

Ось і все, що до цього є. Наразі програма не потрібна. Запустіть гру і спробуйте доторкнутися до іншого предмета.

Думаю, ви можете підтвердити, що якщо ви так штовхнете суперника, суперник буде вести себе так, ніби його штовхають. Користуватися фізикою стандартної функції дуже просто, оскільки програма не потрібна.

Запобігання обертанню об'єктів

Ви можете бачити, коли торкаєтеся його, але якщо точка попадання зміститься хоча б незначно, кожен об'єкт буде обертатися. Як гра вона часто стає неприродною, тому потрібно встановити її так, щоб вона не оберталася.

Rigidbody 2D Компонент має пункт під назвою "Фіксоване обертання" в "Обмеженнях", тому перевірте Z. Тепер можна працювати так, щоб він не обертався. Спробуйте встановити його на два об'єкти і запустити гру, щоб перевірити його.

Я думаю, ви можете бути впевнені, що він не обертається, незалежно від того, з якого кута ви його штовхаєте.

Робіть щось, коли предмети вдаряються один об одного

Наприклад, ви можете захотіти реалізувати кулю, яка вражає ворога, штовхаючи суперника, зменшуючи при цьому здоров'я противника. Це те ж саме, що і попередні поради , так як подія буде відбуватися, тому з ним можна боротися.

Player Відкрийте сценарій і додайте кожне поле і метод, використовуючи наступне:

using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class Player : MonoBehaviour
{
  /// <summary>状態表示用テキストオブジェクト。</summary>
  [SerializeField] private Text TextState;

  // 中略

  /// <summary>衝突した瞬間に呼ばれます。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionEnter2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionStay2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionExit2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }
}

Так як ми хочемо відобразити інформацію про те, потрапив він чи ні, то зробимо можливим відображення її в текстовому об'єкті наступним чином.

/// <summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;

Процес виявлення зіткнень описується наступним чином.

/// <summary>衝突した瞬間に呼ばれます。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
  TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
  TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
  TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

Аналогічно попереднім порадам------, але назва методу тепер "OnCollision------2D" замість "OnTrigger2D".

Rigidbody 2D Кожна з перерахованих вище подій відбувається, коли об'єкт, який зіткнувся з іншим об'єктом Collider 2D , який має . Це дозволить визначити і обробити, правильно це чи ні.

Існує три події, кожна з яких викликається в наступний час.

OnCollisionEnter2D Коли предмети вдаряються один об одного
OnCollisionStay2D Поки об'єкти б'ються один об одного
OnCollisionExit2D Коли об'єкти виходять зі стану зіткнення

В обох випадках об'єкт суперника отримує об'єкт суперника як аргумент, тому ви можете отримати об'єкт суперникаCollision2D, шукаючи Collider2D.gameObject тип ураженої цілі (ворог, Collider2D.collider.tag предмет тощо).

З перерахованих OnCollisionEnter2D вище трьох подій і OnCollisionExit2D викликаються один раз за зіткнення.

OnCollisionStay2D називається кожен кадр під час зіткнення, але подія більше не викликається після того, як пройде певний проміжок часу з моменту зупинки обох об'єктів. Це тому, що вважається, що він увійшов у стан сну, і вважається марною тратою обробки, щоб обчислити зіткнення кожного кадру з чимось, що не рухається.

Якщо ви Rigidbody 2D не хочете, щоб він спав, змініть режим сну параметра на «Не спати».

Після зміни коду задайте текст для відображення інформації.

Запустіть гру і перемістіть об'єкт клавіатурою, щоб доторкнутися до іншого спрайту. Видно, що для кожної викликається по три функції.

До речі, якщо доторкнутися до предмета, а потім перестати рухатися, метод буде викликаний на OnCollisionStay2D короткий час. Ви повинні мати можливість побачити, що метод більше не викликається через OnCollisionStay2D певну кількість часу.

Це говорить про те, що ви увійшли в стан сну, але якщо ви хочете змінити час до входу в цей сон, ви можете змінити його, вибравши в налаштуваннях проекту «2D фізика» і вказавши параметр «Час сну» в секундах. Його не можна встановити в 0, але якщо встановлено OnCollisionStay2D нескінченно малий, сам метод викликати не буде.