Kollisionshåndtering med standardfysik (2D)

Side opdateret :
Dato for oprettelse af side :

Miljø til bekræftelse

Windows
  • Windows 11
Enhedslistens redaktør
  • 2021.3.3f1
Input System Pakke
  • 1.3.0

Forudsætninger for dette tip

Følgende indstillinger er foretaget på forhånd som en forudsætning for beskrivelsen af dette tip.

Først

Dette tip placerer to objekter, så du kan implementere adfærden ved at manipulere et objekt og bruge Unitys standardfysik til at skubbe det andet, når det kommer i kontakt med det andet.

Forresten er de fleste indstillinger de samme som proceduren beskrevet i den foregående artikel "Bestemmelse af, om objekter kolliderer med hinanden (2D)".

Præparation

Proceduren her er næsten den samme som de foregående tip , så lad os flyde det glat.

Når du har oprettet projektet, skal du forberede to sprite-billeder, der vil være objekter, og tilføje dem. Navnene er henholdsvis "UnityTips" og "UnityTips_2".

Tilføj to billedfiler ved at slippe dem i visningen.

Tilføj et script for at flytte det venstre objekt med tastaturet. Scriptnavnet Player er .

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

Vedhæft til det objekt, som du vil køre scriptet på.

Kør spillet og kontroller, om det fungerer med piletasterne på dit tastatur.

Til sidst skal du placere et tekstobjekt for at få vist status for kollisionsregistrering. Objektets navn TextState er .

Indstillinger for kollisionshåndtering

Herfra kan du konfigurere indstillingerne relateret til kollisioner.

Vælg først det objekt, du vil flytte, "UnityTips", og klik på "Tilføj komponent" fra inspektøren. Vælg på Physics 2D listen. Physics er et 3D-objekt, så tag ikke fejl.

Physics 2DBox Collider 2D Vælg mellem . Da denne sprite er rektangulær, vælges Boks, men hvis den f.eks. er cirkelformet, skal du vælge andre figurer, f.eks. Cirkel.

Sidste gang ønskede jeg kun at få oplysninger om, hvorvidt jeg ramte det eller ej, så jeg kontrollerede "Gør det udløser", men denne gang vil jeg ikke. Dette muliggør kollisionshåndtering i fysik.

Rigidbody 2D Tilføj derefter komponenterne i . Du kan tilføje det fra "Fysik 2D -> Rigidbody 2D". Rigidbody giver fysikinformationCollider til objektet og kan også bestemme kollisioner med objekter, der har .

Indstil tyngdekraftsskalaen til 0 for at forhindre frit fald under.

På samme måde skal du tilføje en komponent til det andet objekt "UnityTips_2" for at markere Box Collider 2D hits.

Derudover er det denne gang nødvendigt at bevæge sig med modstanderens kraft,Rigidbody 2D så tilføj . Tyngdekraftsskalaen skal være 0.

Det er alt, hvad der er til det. Intet program er påkrævet på nuværende tidspunkt. Kør spillet og prøv at røre ved et andet objekt.

Jeg tror, du kan bekræfte, at hvis du skubber modstanderen ind på denne måde, vil modstanderen opføre sig, som om han bliver skubbet. Det er meget nemt at bruge standardfunktionens fysik, fordi der ikke kræves noget program.

Forhindre objekter i at rotere

Du kan se, når du rører ved det, men hvis hitpunktet skifter bare lidt, roterer hvert objekt. Som et spil bliver det ofte unaturligt, så du skal indstille det, så det ikke roterer.

Rigidbody 2D Komponenten har et element kaldet "Fast rotation" i "Begrænsninger", så tjek Z. Nu kan du arbejde, så den ikke roterer. Prøv at indstille det til to objekter og køre spillet for at kontrollere det.

Jeg tror, du kan være sikker på, at den ikke roterer, uanset hvilken vinkel du skubber den fra.

Gør noget, når genstande rammer hinanden

For eksempel vil du måske implementere en kugle, der rammer en fjende, mens du skubber modstanderen, mens du reducerer fjendens helbred. Dette er det samme som de tidligere tips , da begivenheden vil forekomme, så du kan håndtere det.

Player Åbn scriptet, og tilføj hvert felt og metode ved hjælp af følgende:

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

Da vi ønsker at vise oplysninger om, hvorvidt det blev ramt eller ej, vil vi gøre det muligt at vise det i et tekstobjekt som følger.

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

Kollisionsdetekteringsprocessen beskrives som følger.

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

I lighed med de tidligere tip------, men metodenavnet er nu "OnCollision------2D" i stedet for "OnTrigger2D".

Rigidbody 2D Hver af ovenstående begivenheder opstår, når et objekt, der har, kolliderer med et andet objekt Collider 2D , der har . Dette giver dig mulighed for at bestemme og behandle, om det er korrekt eller ej.

Der er tre begivenheder, som hver kaldes på følgende tidspunkt.

OnCollisionEnter2D Når objekter rammer hinanden
OnCollisionStay2D Mens objekter rammer hinanden
OnCollisionExit2D Når objekter forlader kollisionstilstanden

I begge tilfælde modtager modstanderobjektet modstanderens objekt som et argument, så du kan få modstanderens Collision2D objekt ved at slå den type mål opCollider2D.gameObject, der rammes af (fjende, Collider2D.collider.tag genstand osv.).

Af de OnCollisionEnter2D ovennævnte tre begivenheder, og OnCollisionExit2D kaldes en gang pr. Kollision.

OnCollisionStay2D kaldes hver ramme under kollisionen, men begivenheden kaldes ikke længere, når der er gået en vis tid, siden begge objekter stoppede. Dette skyldes, at det anses for at være gået i dvaletilstand, og det betragtes som spild af forarbejdning at beregne kollisioner hver ramme med noget, der ikke bevæger sig.

Hvis du ikke vil have den til at sove, skal du Rigidbody 2D ændre parameterens dvaletilstand til "Sov ikke".

Når du har ændret koden, skal du indstille teksten til visning af information.

Kør spillet og flyt objektet med tastaturet for at røre ved en anden sprite. Du kan se, at der kræves tre funktioner for hver.

Forresten, hvis du rører ved et objekt og derefter holder op med at bevæge dig, vil metoden blive kaldt i OnCollisionStay2D kort tid. Du skal kunne se, at metoden ikke længere kaldes efter OnCollisionStay2D en vis tid.

Dette indikerer, at du har indtastet en dvaletilstand, men hvis du vil ændre tiden, indtil du indtaster denne søvn, kan du ændre den ved at vælge "2D Physics" fra projektindstillingerne og angive parameteren "Sleep time" i sekunder. Det kan ikke indstilles til 0, men hvis det OnCollisionStay2D er indstillet til uendeligt lille, vil selve metoden ikke blive kaldt.