ตรวจสอบว่าวัตถุชนกันหรือไม่ (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" และคลิก "เพิ่มส่วนประกอบ" จากตัวตรวจสอบ เลือกจาก Physics 2D รายการ Physics เป็นวัตถุ 3 มิติดังนั้นอย่าทําผิดพลาด

Physics 2DBox Collider 2Dเลือกจาก . เนื่องจากสไปรท์นี้เป็นรูปสี่เหลี่ยมผืนผ้า Box จึงถูกเลือก แต่ถ้าเป็นรูปวงกลม ให้เลือกรูปร่างอื่นๆ เช่น วงกลม

Box Collider 2D เนื่องจากส่วนประกอบจะถูกเพิ่มให้เลือก "ทําให้ทริกเกอร์" จากพารามิเตอร์ สิ่งนี้จะช่วยให้คุณได้รับข้อมูลเกี่ยวกับ "ไม่ว่าคุณจะตีหรือไม่" เท่านั้น

Rigidbody 2Dจากนั้นเพิ่มส่วนประกอบของ . คุณสามารถเพิ่มได้จาก "ฟิสิกส์ 2D -> Rigidbody 2D" Rigidbodyให้ข้อมูลColliderทางฟิสิกส์แก่วัตถุและยังสามารถกําหนดการชนกับวัตถุที่มี .

Rigidbodyอย่างไรก็ตามหากคุณมีส่วนประกอบมันจะมีข้อมูลแรงโน้มถ่วงในทิศทาง -Y ดังนั้นหากคุณดําเนินการมันจะล้มลง ดังนั้นตั้งค่า "มาตราส่วนแรงโน้มถ่วง" เป็น 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 เมื่อวัตถุชนกัน
OnTriggerStay2D ในขณะที่วัตถุกําลังตีกัน
OnTriggerExit2D เมื่อวัตถุออกจากสถานะการชน

ในทั้งสองกรณีวัตถุฝ่ายตรงข้ามจะได้รับวัตถุของฝ่ายตรงข้ามเป็นอาร์กิวเมนต์ดังนั้นคุณสามารถรับวัตถุของCollider2Dฝ่ายตรงข้ามได้โดยค้นหาCollider2D.gameObjectประเภทของเป้าหมายที่ถูกโจมตีโดย (ศัตรูCollider2D.tagไอเท็ม ฯลฯ )

OnTriggerEnter2Dจากสามเหตุการณ์ข้างต้นและOnTriggerExit2Dเรียกว่าหนึ่งครั้งต่อการชนกัน

OnTriggerStay2D เรียกว่าทุกเฟรมระหว่างการชน แต่เหตุการณ์จะไม่ถูกเรียกอีกต่อไปหลังจากเวลาผ่านไประยะหนึ่งเนื่องจากวัตถุทั้งสองหยุดลง นี่เป็นเพราะมันถือว่าได้เข้าสู่สถานะการนอนหลับและถือว่าเป็นการสูญเสียการประมวลผลเพื่อคํานวณการชนทุกเฟรมกับสิ่งที่ไม่เคลื่อนที่

หากคุณ Rigidbody 2D ไม่ต้องการให้เข้าสู่โหมดสลีป ให้เปลี่ยนโหมดสลีปของพารามิเตอร์เป็น "อย่าสลีป"

หลังจากเปลี่ยนรหัสแล้วให้ตั้งค่าข้อความสําหรับการแสดงข้อมูล

เรียกใช้เกมและย้ายวัตถุด้วยแป้นพิมพ์เพื่อสัมผัสสไปรท์อื่น คุณจะเห็นว่ามีการเรียกฟังก์ชั่นสามอย่างสําหรับแต่ละฟังก์ชัน

โดยวิธีการถ้าคุณสัมผัสวัตถุแล้วหยุดเคลื่อนไหววิธีการจะถูกเรียกในช่วงเวลา OnTriggerStay2D สั้น ๆ คุณควรจะเห็นว่าวิธีการนี้ไม่ได้ถูกเรียกอีกต่อไปหลังจาก OnTriggerStay2D ระยะเวลาหนึ่ง

สิ่งนี้บ่งชี้ว่าคุณได้เข้าสู่สถานะสลีปแล้ว แต่ถ้าคุณต้องการเปลี่ยนเวลาจนกว่าคุณจะเข้าสู่โหมดสลีปนี้คุณสามารถเปลี่ยนได้โดยเลือก "ฟิสิกส์ 2 มิติ" จากการตั้งค่าโครงการและระบุพารามิเตอร์ "เวลาสลีป" เป็นวินาที ไม่สามารถตั้งค่าเป็น 0 ได้ แต่ถ้า OnTriggerStay2D ตั้งค่าให้เล็กลงอย่างไม่มีที่สิ้นสุดวิธีการนั้นจะไม่ถูกเรียก