Kollisionshantering med standardfysik (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 placerar två objekt så att du kan implementera beteendet att manipulera ett objekt och använda Unitys standardfysik för att driva det andra när det kommer i kontakt med det andra.

Förresten är de flesta inställningarna desamma som proceduren som beskrivs i föregående artikel "Bestämma om objekt kolliderar med varandra (2D)".

Förberedelse

Förfarandet här är nästan detsamma som tidigare tips , så låt oss flyta det smidigt.

När du har skapat projektet förbereder du två sprite-bilder som ska vara objekt och lägger till dem. 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 .

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
  // 一定時間ごとに呼ばれます
  void FixedUpdate()
  {
    // キーボードの情報を取得
    var keyboard = Keyboard.current;

    // スプライトの移動処理
    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.

Förra gången ville jag bara få information om huruvida jag träffade den eller inte, så jag kollade "Make it trigger", men den här gången kommer jag inte. Detta möjliggör kollisionshantering inom fysiken.

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 .

Ställ in gravitationsskalan på 0 för att förhindra fritt fall under.

På samma sätt lägger du till en komponent i det andra objektet "UnityTips_2" för att markera Box Collider 2D träffar.

Dessutom är den här gången det nödvändigt att flytta med motståndarens kraft,Rigidbody 2D så lägg till . Tyngdkraftsskalan ska vara 0.

Det är allt som finns i det. Inget program krävs just nu. Kör spelet och försök att röra vid ett annat objekt.

Jag tror att du kan bekräfta att om du trycker in motståndaren så här kommer motståndaren att bete sig som om han knuffas. Det är mycket enkelt att använda standardfunktionens fysik eftersom inget program krävs.

Förhindra att objekt roterar

Du kan se när du trycker på den, men om träffpunkten flyttas till och med något roteras varje objekt. Som ett spel blir det ofta onaturligt, så du måste ställa in det så att det inte roterar.

Rigidbody 2D Komponenten har ett objekt som heter "Fast rotation" i "Begränsningar", så kontrollera Z. Nu kan du arbeta så att den inte roterar. Försök att ställa in det på två objekt och köra spelet för att kontrollera det.

Jag tror att du kan vara säker på att den inte roterar oavsett vilken vinkel du trycker den från.

Gör något när föremål träffar varandra

Till exempel kanske du vill implementera en kula som träffar en fiende medan du skjuter motståndaren samtidigt som fiendens hälsa minskar. Detta är detsamma som tidigare tips , eftersom händelsen kommer att inträffa, så att du kan hantera det.

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 OnCollisionEnter2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionStay2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
  }

  /// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
  /// <param name="partner">衝突した相手のコリジョン情報。</param>
  private void OnCollisionExit2D(Collision2D partner)
  {
    TextState.text = $"OnCollisionExit2D : {partner.collider.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 OnCollisionEnter2D(Collision2D partner)
{
  TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
  TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

/// <summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
/// <param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
  TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}

Liknar de tidigare tipsen------, men metodnamnet är nu "OnCollision------2D" istället för "OnTrigger2D".

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.

OnCollisionEnter2D När objekt träffar varandra
OnCollisionStay2D Medan föremål träffar varandra
OnCollisionExit2D 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 Collision2D objekt genom att leta upp Collider2D.gameObject vilken typ av mål som träffas av (fiende, objekt, Collider2D.collider.tag etc.).

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

OnCollisionStay2D 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 OnCollisionStay2D en kort tid. Du bör kunna se att metoden inte längre anropas efter OnCollisionStay2D 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 OnCollisionStay2D är inställd på oändligt liten kommer själva metoden inte att kallas.