Avgöra om objekt kolliderar med varandra (2D)

Sidan uppdaterad :
Datum för skapande av sida :

Verifiering miljö

Windows
  • Fönster 11
Unity-redaktör
  • 2021.3.3F1
Paket för inmatningssystem
  • 1.3.0

Förutsättningar för det här tipset

Följande inställningar har gjorts i förväg som en förutsättning för beskrivningen av detta tips.

Först

Det här tipset förklarar hur du avgör om två objekt är i kontakt. Flytta ett objekt med tangentbordet.

Förberedelse

När du har skapat projektet förbereder du två bilder av sprite som kommer att vara objektet. Om du är besvärlig att förbereda kan du placera två identiska sprites, men den här gången kommer vi att separera dem för tydlighetens skull. Namnen är "UnityTips" respektive "UnityTips_2".

Lägg till två bildfiler genom att släppa dem i vyn.

Lägg till ett skript för att flytta det vänstra objektet med tangentbordet. Skriptnamnet Player är . Skriptinnehållet liknar tipsen i Flytta, rotera och skala en 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);
    }
  }
}

Koppla till objektet som du vill köra skriptet på.

Kör spelet och kontrollera om det fungerar med markörknapparna på tangentbordet.

Slutligen placerar du ett textobjekt för att visa kollisionsdetekteringsstatus. Objektnamnet TextState är .

Inställningar för kollisionshantering

Härifrån kan du konfigurera inställningarna relaterade till kollisioner.

Välj först objektet du vill flytta, "UnityTips" och klicka på "Lägg till komponent" från inspektören. Välj från Physics 2D listan. Physics är ett 3D-objekt, så gör inga misstag.

Physics 2DBox Collider 2D Välj från . Eftersom den här spriten är rektangulär markeras Ruta, men om den är cirkelformad markerar du till exempel andra former som Cirkel.

Box Collider 2D Eftersom komponenten kommer att läggas till, markera "Gör det utlöst" från parametrarna. Detta gör att du bara kan få information om "om du träffar eller inte".

Rigidbody 2D Lägg sedan till komponenterna i . Du kan lägga till den från "Physics 2D -> Rigidbody 2D". Rigidbody ger fysikinformationCollider till objektet och kan också bestämma kollisioner med objekt som har .

Rigidbody Men om du har en komponent kommer den också att innehålla tyngdkraftsinformation i -Y-riktningen, så om du kör den kommer den att falla ner. Så ställ in "Gravity Scale" till 0 från parametrarna.

Förresten, om det är ett sidscrollande actionspel, kan det vara bekvämt att använda tyngdkraftsskalan i den meningen att det är fritt fall ner.

På samma sätt lägger du till en komponent i det Box Collider 2D andra objektet "UnityTips_2". Det här är den drabbade sidan den här gången, så du behöver inte ändra några inställningar.

Player Öppna skriptet och lägg till varje fält och metod på följande sätt:

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

Eftersom vi vill visa information om huruvida den träffades eller inte, gör vi det möjligt att visa den i ett textobjekt enligt följande.

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

Kollisionsdetekteringsprocessen beskrivs enligt följande.

/// <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 Var och en av ovanstående händelser inträffar när ett objekt som har kolliderar med ett annat objekt Collider 2D som har . Detta gör att du kan bestämma och bearbeta om det är korrekt eller inte.

Det finns tre händelser, som var och en kallas vid följande tidpunkt.

OnTriggerEnter2D När objekt träffar varandra
OnTriggerStay2D Medan föremål träffar varandra
OnTriggerExit2D När föremål lämnar kollisionstillståndet

I båda fallen tar motståndarens objekt emot motståndarens objekt som ett argument, så du kan få motståndarens Collider2D objekt genom att leta upp Collider2D.gameObject vilken typ av mål som träffas av (fiende, objekt, Collider2D.tag etc.).

Av ovanstående OnTriggerEnter2D tre händelser, och OnTriggerExit2D kallas en gång per kollision.

OnTriggerStay2D kallas varje bildruta under kollisionen, men händelsen anropas inte längre efter att en viss tid har gått sedan båda objekten stannade. Detta beror på att det anses ha gått in i viloläge, och det anses vara slöseri med bearbetning att beräkna kollisioner varje ram med något som inte rör sig.

Om du Rigidbody 2D inte vill att den ska sova, ändra parameterns viloläge till "Sov inte".

När du har ändrat koden ställer du in texten för att visa information.

Kör spelet och flytta objektet med tangentbordet för att röra vid en annan sprite. Du kan se att tre funktioner kallas för var och en.

Förresten, om du rör vid ett objekt och sedan slutar röra dig, kommer metoden att kallas under OnTriggerStay2D en kort tid. Du bör kunna se att metoden inte längre anropas efter OnTriggerStay2D en viss tid.

Detta indikerar att du har gått in i ett viloläge, men om du vill ändra tiden tills du går in i denna sömn kan du ändra den genom att välja "2D-fysik" från projektinställningarna och ange parametern "Viloläge" på några sekunder. Den kan inte ställas in på 0, men om den OnTriggerStay2D är inställd på oändligt liten kommer själva metoden inte att kallas.