Determine if objects collide with each other (2D)

Page update date :
Page creation date :

Verification environment

Windows
  • Windows 11
Unity Editor
  • 2021.3.3f1
Input System Package
  • 1.3.0

Prerequisites for this tip

The following settings have been made in advance as a premise for the description of this tip.

At first

This tip explains how to determine if two objects are in contact. Move one object with the keyboard.

Preparation

After creating the project, prepare two images of the sprite that will be the object. If you are troublesome to prepare, you can place two identical sprites, but this time we will separate them for clarity. The names are "UnityTips" and "UnityTips_2" respectively.

Add two image files by dropping them into the view.

Add a script to move the left object with the keyboard. The script name Player is . The script content is similar to the tips in Move, rotate, and scale a sprite.

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

Attach to the object on which you want to run the script.

Run the game and check if it works with the cursor keys on your keyboard.

Finally, place a text object to display the collision detection status. The object name TextState is .

Collision Handling Settings

From here, you can configure the settings related to collisions.

First, select the object you want to move, "UnityTips", and click "Add Component" from the inspector. Select from Physics 2D the list. Physics is a 3D object, so make no mistake.

Physics 2DBox Collider 2D Select from . Since this sprite is rectangular, Box is selected, but if it is circle-shaped, for example, select other shapes such as Circle.

Box Collider 2D Since the component will be added, check "Make it trigger" from the parameters. This will allow you to get information only about "whether you hit or not".

Rigidbody 2D Then add the components of . You can add it from "Physics 2D -> Rigidbody 2D". Rigidbody gives physics informationCollider to the object and can also determine collisions with objects that have .

Rigidbody However, if you have a component, it will also contain gravity information in the -Y direction, so if you execute it, it will fall down. So set the "Gravity Scale" to 0 from the parameters.

By the way, if it is a side-scrolling action game, it may be convenient to use the gravity scale in the sense that it is free fall down.

Similarly, add a component to the Box Collider 2D other object "UnityTips_2". This is the affected side this time, so you don't need to change any settings.

Player Open the script and add each field and method using as follows:

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

Since we want to display information on whether or not it was hit, we will make it possible to display it in a text object as follows.

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

The collision detection process is described as follows.

/// <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 Each of the above events occurs when an object that has collides with another object Collider 2D that has . This will allow you to determine and process whether it is correct or not.

There are three events, each of which is called at the following timing.

OnTriggerEnter2D When objects hit each other
OnTriggerStay2D While objects are hitting each other
OnTriggerExit2D When objects leave the collision state

In both cases, the opponent object receives the opponent's object as an argument, so you can get the opponent's Collider2D object by looking up Collider2D.gameObject the type of target hit by (enemy, Collider2D.tag item, etc.).

Of the OnTriggerEnter2D above three events, and OnTriggerExit2D are called once per collision.

OnTriggerStay2D is called every frame during the collision, but the event is no longer called after a certain amount of time has passed since both objects stopped. This is because it is considered to have entered a sleep state, and it is considered a waste of processing to calculate collisions every frame with something that is not moving.

If you Rigidbody 2D do not want it to sleep, change the sleep mode of the parameter to "Do not sleep".

After changing the code, set the text for displaying information.

Run the game and move the object with the keyboard to touch another sprite. You can see that three functions are called for each.

By the way, if you touch an object and then stop moving, the method will be called for OnTriggerStay2D a short time. You should be able to see that the method is no longer called after OnTriggerStay2D a certain amount of time.

This indicates that you have entered a sleep state, but if you want to change the time until you enter this sleep, you can change it by selecting "2D Physics" from the project settings and specifying the "Sleep time" parameter in seconds. It cannot be set to 0, but if it OnTriggerStay2D is set to infinitely small, the method itself will not be called.