객체가 서로 충돌하는지 확인(2D)

페이지 업데이트 :
페이지 생성 날짜 :

검증 환경

윈도우
  • 윈도우 11
Unity 에디터
  • 2021.3.3f1
입력 시스템 패키지
  • 1.3.0

이 팁의 전제 조건

이 팁에 대한 설명의 전제로 다음 설정이 미리 이루어졌습니다.

처음에

이 팁은 두 개체가 접촉하고 있는지 확인하는 방법을 설명합니다. 키보드로 한 개체를 이동합니다.

준비

프로젝트를 만든 후 개체가 될 스프라이트의 두 이미지를 준비합니다. 준비하기가 번거롭다면 두 개의 동일한 스프라이트를 배치할 수 있지만 이번에는 명확성을 위해 분리합니다. 이름은 각각 "UnityTips"와 "UnityTips_2"입니다.

두 개의 이미지 파일을 뷰에 놓아 추가합니다.

키보드로 왼쪽 개체를 이동하는 스크립트를 추가합니다. 스크립트 이름은 Player 입니다. 스크립트 내용은 스프라이트 이동, 회전 및 크기 조정의 팁과 비슷합니다.

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);
    }
  }
}

스크립트를 실행할 개체에 연결합니다.

게임을 실행하고 키보드의 커서 키와 함께 작동하는지 확인하십시오.

마지막으로 충돌 감지 상태를 표시할 텍스트 개체를 배치합니다. 개체 이름은 TextState 입니다.

충돌 처리 설정

여기에서 충돌과 관련된 설정을 구성할 수 있습니다.

먼저 이동할 오브젝트인 "UnityTips"를 선택하고 인스펙터에서 "Add Component"를 클릭합니다. Physics 2D 목록에서 선택합니다. Physics 는 3D 개체이므로 실수하지 마십시오.

Physics 2DBox Collider 2D 에서 선택합니다. 이 스프라이트는 직사각형이므로 Box가 선택되지만 예를 들어 원 모양인 경우 Circle과 같은 다른 모양을 선택합니다.

Box Collider 2D 구성 요소가 추가되므로 매개 변수에서 "트리거로 만들기"를 선택하십시오. 이렇게 하면 "타격 여부"에 대한 정보만 얻을 수 있습니다.

Rigidbody 2D 그런 다음 의 구성 요소를 추가합니다. "Physics 2D -> Rigidbody 2D"에서 추가할 수 있습니다. Rigidbody 객체에 물리 정보를Collider 제공하고 .

Rigidbody 그러나 구성 요소가 있으면 -Y 방향의 중력 정보도 포함되므로 실행하면 떨어집니다. 따라서 매개변수에서 "Gravity Scale"을 0으로 설정합니다.

덧붙여서 횡스크롤 액션 게임이라면 자유낙하라는 의미에서 중력계를 사용하는 것이 편리할지도 모릅니다.

마찬가지로 다른 개체 "UnityTips_2"에 Box Collider 2D 구성 요소를 추가합니다. 이번에는 영향을 받는 쪽이므로 설정을 변경할 필요가 없습니다.

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 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}";
  }
}

맞았는지 여부에 대한 정보를 표시하고 싶기 때문에 다음과 같이 텍스트 객체에 표시할 수 있도록 합니다.

/// <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}";
}

Rigidbody 2D 위의 각 이벤트는 있는 개체가 있는 다른 개체 Collider 2D 와 충돌할 때 발생합니다. 이를 통해 올바른지 여부를 결정하고 처리할 수 있습니다.

세 가지 이벤트가 있으며 각 이벤트는 다음 타이밍에 호출됩니다.

OnTriggerEnter2D 물체가 서로 부딪힐 때
온트리거스테이2D 물체가 서로 부딪히는 동안
OnTriggerExit2D 객체가 충돌 상태를 벗어날 때

두 경우 모두 상대 객체가 상대의 객체를 인자로 받아들이기 때문에 적중한 타겟의 종류(적, Collider2D.tag 아이템 등)를 조회 Collider2D.gameObject 하여 상대 Collider2D 의 객체를 얻을 수 있습니다.

OnTriggerEnter2D 위의 세 가지 이벤트 OnTriggerExit2D 중 충돌당 한 번 호출됩니다.

OnTriggerStay2D 는 충돌 중에 매 프레임마다 호출되지만, 두 오브젝트가 모두 중지된 후 일정 시간이 경과한 후에는 더 이상 이벤트가 호출되지 않습니다. 이는 수면 상태에 들어간 것으로 간주되기 때문이며, 움직이지 않는 무언가와 매 프레임마다 충돌을 계산하는 것은 처리 낭비로 간주됩니다.

Rigidbody 2D 절전 모드를 사용하지 않으려면 매개 변수의 절전 모드를 "절전 모드 안 함"으로 변경하십시오.

코드를 변경한 후 정보를 표시할 텍스트를 설정합니다.

게임을 실행하고 키보드로 개체를 움직여 다른 스프라이트를 터치합니다. 각각에 대해 세 개의 함수가 호출되는 것을 볼 수 있습니다.

그건 그렇고, 물체를 만진 다음 움직임을 멈추면 짧은 시간 동안 OnTriggerStay2D 메서드가 호출됩니다. 일정 시간이 지나면 OnTriggerStay2D 메서드가 더 이상 호출되지 않는 것을 볼 수 있어야 합니다.

이는 절전 상태에 들어갔음을 나타내지만, 이 절전 모드로 들어갈 때까지의 시간을 변경하려면 프로젝트 설정에서 "2D 물리"를 선택하고 "절전 시간" 매개변수를 초 단위로 지정하여 변경할 수 있습니다. 0으로 설정할 수는 없지만 OnTriggerStay2D 무한히 작게 설정하면 메서드 자체가 호출되지 않습니다.