确定对象是否相互碰撞 (2D)

更新页 :
页面创建日期 :

验证环境

窗户
  • 视窗 11
统一编辑器
  • 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”,然后从检查器中单击“添加组件”。 从 Physics 2D 列表中选择。 Physics 是一个 3D 对象,所以不要搞错。

Physics 2DBox Collider 2D从中选择。 由于此子画面是矩形的,因此会选择Box,但如果它是圆形的,例如,请选择其他形状,例如圆形。

Box Collider 2D 由于将添加组件,请从参数中选中“使其触发”。 这将允许您仅获取有关“是否击中”的信息。

Rigidbody 2D然后添加 的组件。 您可以从“物理 2D -> 刚体 2D”中添加它。 Rigidbody为对象提供物理信息Collider,还可以确定与具有 的对象的碰撞。

Rigidbody但是,如果你有一个组件,它还将包含 -Y 方向的重力信息,所以如果你执行它,它会掉下来。 因此,从参数中将“重力刻度”设置为 0。

顺便说一句,如果是横向卷轴动作游戏,那么在自由落体的意义上使用重力刻度可能会很方便。

同样,将组件 Box Collider 2D 添加到另一个对象“UnityTips_2”。 这次是受影响的一侧,因此您无需更改任何设置。

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 当物体相互撞击时
OnTriggerStay2D 当物体相互撞击时
OnTriggerExit2D 当对象离开碰撞状态时

在这两种情况下,对手对象接收对手的对象作为参数,因此您可以通过查找Collider2D.gameObject击中的目标类型(敌人、Collider2D.tag物品等)来获取对手的对象Collider2D

OnTriggerEnter2D以上三个事件中,每次OnTriggerExit2D碰撞调用一次。

OnTriggerStay2D 在碰撞期间每帧调用一次,但在两个对象都停止后经过一定时间后不再调用该事件。 这是因为它被认为已进入睡眠状态,并且计算与不移动的东西的每一帧碰撞被认为是浪费处理。

如果 Rigidbody 2D 不希望它进入睡眠状态,请将参数的睡眠模式更改为“不睡眠”。

更改代码后,设置用于显示信息的文本。

运行游戏并使用键盘移动对象以触摸另一个精灵。 您可以看到为每个函数调用了三个函数。

顺便说一下,如果您触摸一个对象然后停止移动,则会在短时间内调用 OnTriggerStay2D 该方法。 您应该能够看到该方法在一段时间后 OnTriggerStay2D 不再被调用。

这表示您已进入睡眠状态,但如果您想更改进入此睡眠之前的时间,您可以通过从项目设置中选择“2D Physics”并指定“睡眠时间”参数(以秒为单位)来更改它。 它不能设置为 0,但如果设置为 OnTriggerStay2D 无限小,则不会调用方法本身。