Xác định xem các vật thể có va chạm với nhau không (2D)

Trang Cập Nhật :
Ngày tạo trang :

Môi trường xác minh

Windows
  • cửa sổ 11
Biên tập viên Unity
  • 2021.3.3F1
Gói hệ thống đầu vào
  • 1.3.0

Điều kiện tiên quyết cho mẹo này

Các cài đặt sau đây đã được thực hiện trước làm tiền đề cho mô tả về mẹo này.

Lúc đầu

Mẹo này giải thích cách xác định xem hai đối tượng có tiếp xúc với nhau hay không. Di chuyển một đối tượng bằng bàn phím.

Chuẩn bị

Sau khi tạo dự án, chuẩn bị hai hình ảnh của sprite sẽ là đối tượng. Nếu bạn gặp rắc rối khi chuẩn bị, bạn có thể đặt hai sprite giống hệt nhau, nhưng lần này chúng tôi sẽ tách chúng ra cho rõ ràng. Tên lần lượt là "UnityTips" và "UnityTips_2".

Thêm hai tệp hình ảnh bằng cách thả chúng vào chế độ xem.

Thêm tập lệnh để di chuyển đối tượng bên trái bằng bàn phím. Tên Player tập lệnh là . Nội dung tập lệnh tương tự như các mẹo trong Di chuyển, xoay và chia tỷ lệ 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);
    }
  }
}

Đính kèm vào đối tượng mà bạn muốn chạy tập lệnh.

Chạy trò chơi và kiểm tra xem nó có hoạt động với các phím con trỏ trên bàn phím của bạn không.

Cuối cùng, đặt một đối tượng văn bản để hiển thị trạng thái phát hiện va chạm. Tên TextState đối tượng là .

Cài đặt xử lý va chạm

Từ đây, bạn có thể định cấu hình các cài đặt liên quan đến va chạm.

Đầu tiên, chọn đối tượng bạn muốn di chuyển, "UnityTips" và nhấp vào "Thêm thành phần" từ trình kiểm tra. Chọn từ Physics 2D danh sách. Physics là một đối tượng 3D, vì vậy đừng nhầm lẫn.

Physics 2DBox Collider 2D Chọn từ . Vì sprite này là hình chữ nhật, Box được chọn, nhưng nếu nó có hình tròn, ví dụ, hãy chọn các hình dạng khác như Hình tròn.

Box Collider 2D Vì thành phần sẽ được thêm vào, hãy kiểm tra "Làm cho nó kích hoạt" từ các tham số. Điều này sẽ cho phép bạn chỉ nhận được thông tin về "cho dù bạn có đánh hay không".

Rigidbody 2D Sau đó thêm các thành phần của . Bạn có thể thêm nó từ "Vật lý 2D -> Rigidbody 2D". Rigidbody cung cấp thông tinCollider vật lý cho đối tượng và cũng có thể xác định va chạm với các vật thể có .

Rigidbody Tuy nhiên, nếu bạn có một thành phần, nó cũng sẽ chứa thông tin trọng lực theo hướng -Y, vì vậy nếu bạn thực hiện nó, nó sẽ rơi xuống. Vì vậy, hãy đặt "Thang đo trọng lực" thành 0 từ các tham số.

Nhân tiện, nếu đây là một trò chơi hành động cuộn bên, có thể thuận tiện khi sử dụng thang trọng lực theo nghĩa là nó rơi tự do.

Tương tự, thêm một thành phần vào Box Collider 2D đối tượng khác "UnityTips_2". Đây là bên bị ảnh hưởng lần này, vì vậy bạn không cần thay đổi bất kỳ cài đặt nào.

Player Mở script và thêm từng trường, phương thức sử dụng như sau:

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

Vì chúng tôi muốn hiển thị thông tin về việc nó có bị bắn trúng hay không, chúng tôi sẽ làm cho nó có thể hiển thị nó trong một đối tượng văn bản như sau.

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

Quá trình phát hiện va chạm được mô tả như sau.

/// <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 Mỗi sự kiện trên xảy ra khi một vật thể đã va chạm với một vật thể Collider 2D khác có . Điều này sẽ cho phép bạn xác định và xử lý xem nó có đúng hay không.

Có ba sự kiện, mỗi sự kiện được gọi vào thời điểm sau.

OnTriggerEnter2D Khi các vật thể va vào nhau
OnTriggerStay2D Trong khi các vật thể đang va vào nhau
OnTriggerExit2D Khi các vật thể rời khỏi trạng thái va chạm

Trong cả hai trường hợp, đối tượng đối thủ nhận đối tượng của đối thủ làm đối số, vì vậy bạn có thể lấy đối tượng của Collider2D đối thủ bằng cách tra cứu Collider2D.gameObject loại mục tiêu bị bắn trúng (kẻ thù, vật phẩm, Collider2D.tag v.v.).

Trong OnTriggerEnter2D ba sự kiện trên, và OnTriggerExit2D được gọi một lần cho mỗi vụ va chạm.

OnTriggerStay2D được gọi là mọi khung hình trong vụ va chạm, nhưng sự kiện không còn được gọi sau một khoảng thời gian nhất định đã trôi qua kể từ khi cả hai vật thể dừng lại. Điều này là do nó được coi là đã đi vào trạng thái ngủ và nó được coi là lãng phí xử lý để tính toán va chạm mọi khung hình với thứ gì đó không chuyển động.

Nếu bạn Rigidbody 2D không muốn nó ngủ, hãy thay đổi chế độ ngủ của tham số thành "Không ngủ".

Sau khi thay đổi mã, hãy đặt văn bản để hiển thị thông tin.

Chạy trò chơi và di chuyển đối tượng bằng bàn phím để chạm vào một sprite khác. Bạn có thể thấy rằng ba hàm được gọi cho mỗi.

Nhân tiện, nếu bạn chạm vào một vật thể và sau đó ngừng di chuyển, phương thức sẽ được gọi trong OnTriggerStay2D một thời gian ngắn. Bạn sẽ có thể thấy rằng phương thức không còn được gọi sau OnTriggerStay2D một khoảng thời gian nhất định.

Điều này cho biết rằng bạn đã nhập trạng thái ngủ, nhưng nếu bạn muốn thay đổi thời gian cho đến khi vào giấc ngủ này, bạn có thể thay đổi nó bằng cách chọn "Vật lý 2D" từ cài đặt dự án và chỉ định tham số "Thời gian ngủ" tính bằng giây. Nó không thể được đặt thành 0, nhưng nếu nó OnTriggerStay2D được đặt thành nhỏ vô hạn, bản thân phương thức sẽ không được gọi.