Określanie, czy obiekty kolidują ze sobą (2D)

Strona zaktualizowana :
Data utworzenia strony :

Środowisko weryfikacji

Windows
  • Okna 11
Edytor Unity
  • 2021.3.3f1
Pakiet systemu wejściowego
  • 1.3.0

Wymagania wstępne dotyczące tej porady

Poniższe ustawienia zostały wcześniej wprowadzone jako przesłanka do opisu tej wskazówki.

Na początku

W tej wskazówce wyjaśniono, jak ustalić, czy dwa obiekty są w kontakcie. Przenoszenie jednego obiektu za pomocą klawiatury.

Preparat

Po utworzeniu projektu przygotuj dwa obrazy duszka, który będzie obiektem. Jeśli jesteś kłopotliwy w przygotowaniu, możesz umieścić dwa identyczne duszki, ale tym razem rozdzielimy je dla jasności. Nazwy to odpowiednio "UnityTips" i "UnityTips_2".

Dodaj dwa pliki obrazów, upuszczając je w widoku.

Dodaj skrypt, aby przesunąć lewy obiekt za pomocą klawiatury. Nazwa skryptu Player to . Zawartość skryptu jest podobna do porad w temacie Przenoszenie, obracanie i skalowanie duszka.

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
  // 一定時間ごとに呼ばれます
  void FixedUpdate()
  {
    // キーボードの情報を取得
    var keyboard = Keyboard.current;
    if (keyboard == null)
    {
      Debug.Log("キーボードがありません。");
      return;
    }

    // スプライトの移動処理
    // Translate メソッドでスプライトの位置が移動します
    // Space.World を指定すると回転の影響をうけません
    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);
    }
  }
}

Dołącz do obiektu, na którym chcesz uruchomić skrypt.

Uruchom grę i sprawdź, czy działa z kursora na klawiaturze.

Na koniec umieść obiekt tekstowy, aby wyświetlić stan wykrycia kolizji. Nazwa obiektu TextState to .

Ustawienia obsługi kolizji

W tym miejscu możesz skonfigurować ustawienia związane z kolizjami.

Najpierw wybierz obiekt, który chcesz przenieść, "UnityTips" i kliknij "Dodaj komponent" od inspektora. Wybierz z Physics 2D listy. Physics jest obiektem 3D, więc nie popełnij błędu.

Physics 2DBox Collider 2D Wybierz z . Ponieważ ten duszek jest prostokątny, pole jest zaznaczone, ale jeśli na przykład ma kształt koła, zaznacz inne kształty, takie jak Okrąg.

Box Collider 2D Ponieważ komponent zostanie dodany, zaznacz "Uruchom go" z parametrów. Pozwoli to uzyskać informacje tylko o tym, "czy trafiłeś, czy nie".

Rigidbody 2D Następnie dodaj składniki . Możesz go dodać z "Physics 2D -> Rigidbody 2D". Rigidbody Daje informacjeCollider fizyczne do obiektu, a także może określać kolizje z obiektami, które mają .

Rigidbody Jeśli jednak masz komponent, będzie on również zawierał informacje o grawitacji w kierunku -Y, więc jeśli go wykonasz, spadnie. Ustaw więc "Skalę grawitacji" na 0 z parametrów.

Nawiasem mówiąc, jeśli jest to przewijana gra akcji, wygodne może być użycie skali grawitacji w tym sensie, że jest to swobodny spadek.

Podobnie, dodaj komponent do Box Collider 2D innego obiektu "UnityTips_2". Tym razem jest to strona dotknięta problemem, więc nie musisz zmieniać żadnych ustawień.

Player Otwórz skrypt i dodaj każde pole i metodę, korzystając z następujących czynności:

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 OnTriggerEnter2D(Collider2D partner)
  {
    TextState.text = $"OnTriggerEnter2D : {partner.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

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

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

Ponieważ chcemy wyświetlić informacje o tym, czy został trafiony, umożliwimy wyświetlenie go w obiekcie tekstowym w następujący sposób.

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

Proces wykrywania kolizji jest opisany w następujący sposób.

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

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

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

Rigidbody 2D Każde z powyższych zdarzeń występuje, gdy obiekt, który ma koliduje z innym obiektem Collider 2D , który ma . Pozwoli to określić i przetworzyć, czy jest poprawny, czy nie.

Istnieją trzy wydarzenia, z których każde jest zwoływane w następującym czasie.

OnTriggerEnter2D Gdy obiekty uderzają o siebie
OnTriggerStay2D Podczas gdy obiekty uderzają o siebie
OnTriggerExit2D Gdy obiekty opuszczają stan kolizji

W obu przypadkach obiekt przeciwnika otrzymuje obiekt przeciwnika jako argument, dzięki czemu możesz uzyskać obiekt przeciwnikaCollider2D, wyszukując Collider2D.gameObject typ trafionego celu (wróg, Collider2D.tag przedmiot itp.).

Z OnTriggerEnter2D powyższych trzech zdarzeń i OnTriggerExit2D są wywoływane raz na kolizję.

OnTriggerStay2D jest wywoływana jako każda klatka podczas kolizji, ale zdarzenie nie jest już wywoływane po upływie określonego czasu od zatrzymania obu obiektów. Dzieje się tak dlatego, że uważa się, że wszedł w stan uśpienia, a obliczanie kolizji każdej klatki z czymś, co się nie porusza, jest uważane za marnotrawstwo przetwarzania.

Jeśli nie Rigidbody 2D chcesz, aby spał, zmień tryb uśpienia parametru na "Nie śpij".

Po zmianie kodu ustaw tekst do wyświetlania informacji.

Uruchom grę i przesuń obiekt za pomocą klawiatury, aby dotknąć innego duszka. Widać, że dla każdej z nich wywoływane są trzy funkcje.

Nawiasem mówiąc, jeśli dotkniesz obiektu, a następnie przestaniesz się poruszać, metoda zostanie wywołana na OnTriggerStay2D krótki czas. Powinieneś być w stanie zobaczyć, że metoda nie jest już wywoływana po OnTriggerStay2D pewnym czasie.

Oznacza to, że wszedłeś w stan uśpienia, ale jeśli chcesz zmienić czas do wejścia w ten sen, możesz go zmienić, wybierając "Fizyka 2D" z ustawień projektu i określając parametr "Czas uśpienia" w sekundach. Nie można go ustawić na 0, ale jeśli jest OnTriggerStay2D ustawiony na nieskończenie mały, sama metoda nie zostanie wywołana.