Řešení kolizí pomocí standardní fyziky (2D)

Stránky aktualizovány :
Datum vytvoření stránky :

Ověřovací prostředí

Windows
  • Systém Windows 11
Editor jednoty
  • 2021.3.3f1
Vstupní systémový balíček
  • 1.3.0

Předpoklady pro tento tip

Následující nastavení byla provedena předem jako předpoklad pro popis tohoto tipu.

Nejprve

Tento tip umístí dva objekty, abyste mohli implementovat chování manipulace s jedním objektem a pomocí standardní fyziky Unity tlačit druhý, když přijde do kontaktu s druhým.

Mimochodem, většina nastavení je stejná jako postup popsaný v předchozím článku "Určení, zda objekty kolidují (2D)".

Příprava

Postup je zde téměř stejný jako předchozí tipy , takže to hladce procházíme.

Po vytvoření projektu připravte dva pohyblivé symboly, které budou objekty a přidejte je. Názvy jsou "UnityTips" a "UnityTips_2".

Přidejte dva obrazové soubory tak, že je přetáhnete do zobrazení.

Přidejte skript pro přesunutí levého objektu pomocí klávesnice. Název skriptu Player je .

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

Připojte se k objektu, na kterém chcete skript spustit.

Spusťte hru a zkontrolujte, zda funguje s kurzorovými klávesami na klávesnici.

Nakonec umístěte textový objekt, který zobrazí stav detekce kolizí. Název objektu TextState je .

Nastavení řešení kolizí

Zde můžete konfigurovat nastavení související s kolizemi.

Nejprve vyberte objekt, který chcete přesunout, "UnityTips", a v inspektoru klikněte na "Přidat komponentu". Vyberte ze Physics 2D seznamu. Physics je 3D objekt, takže se nenechte zmýlit.

Physics 2DBox Collider 2D Vyberte z . Protože je tento pohyblivý symbol obdélníkový, je vybrán Rámeček, ale pokud má například tvar kruhu, vyberte jiné tvary, například Kruh.

Minule jsem chtěl získat informace pouze o tom, zda jsem to trefil nebo ne, takže jsem zaškrtl "Make it trigger", ale tentokrát to neudělám. To umožňuje zvládání kolizí ve fyzice.

Rigidbody 2D Pak přidejte komponenty . Můžete jej přidat z "Physics 2D -> Rigidbody 2D". Rigidbody poskytuje fyzikální informaceCollider objektu a může také určit kolize s objekty, které mají .

Nastavte stupnici gravitace na 0, abyste zabránili volnému pádu níže.

Podobně přidejte komponentu k jinému objektu "UnityTips_2" pro označení Box Collider 2D výsledků.

Kromě toho je tentokrát nutné se pohybovat silou soupeře,Rigidbody 2D takže přidejte . Stupnice gravitace by měla být 0.

To je vše. V tuto chvíli není vyžadován žádný program. Spusťte hru a pokuste se dotknout jiného objektu.

Myslím, že můžete potvrdit, že pokud takto strčíte soupeře, soupeř se bude chovat, jako by byl strčen. Je velmi snadné použít fyziku standardní funkce, protože není vyžadován žádný program.

Zabránění otáčení objektů

Můžete vidět, když se ho dotknete, ale pokud se bod zásahu posune i nepatrně, každý objekt se otočí. Jako hra se často stává nepřirozenou, takže ji musíte nastavit tak, aby se neotáčela.

Rigidbody 2D Komponenta má položku nazvanou "Pevná rotace" v "Omezeních", takže zkontrolujte Z. Nyní můžete pracovat tak, aby se neotáčel. Zkuste jej nastavit na dva objekty a spustit hru, abyste ji zkontrolovali.

Myslím, že si můžete být jisti, že se neotáčí bez ohledu na to, z jakého úhlu ji tlačíte.

Udělejte něco, když do sebe předměty narazí

Můžete například chtít implementovat kulku, která zasáhne nepřítele, zatímco tlačí na soupeře a zároveň snižuje jeho zdraví. To je stejné jako předchozí tipy , protože událost nastane, takže se s ní můžete vypořádat.

Player Otevřete skript a přidejte každé pole a metodu následujícím způsobem:

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

Protože chceme zobrazit informace o tom, zda byl nebo nebyl zasažen, umožníme jej zobrazit v textovém objektu následujícím způsobem.

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

Proces detekce kolizí je popsán následovně.

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

Podobně jako u předchozích tipů------, ale název metody je nyní "OnCollision------2D" namísto "OnTrigger2D".

Rigidbody 2D Každá z výše uvedených událostí nastane, když objekt, který má kolize s jiným objektem Collider 2D , který má . To vám umožní určit a zpracovat, zda je to správné nebo ne.

Existují tři události, z nichž každá je vyvolána v následujícím čase.

OnCollisionEnter2D Když do sebe objekty narazí
OnCollisionStay2D Zatímco objekty do sebe narážejí
OnCollisionExit2D Když objekty opustí kolizní stav

V obou případech soupeřův objekt obdrží soupeřův objekt jako argument, takže můžete získat soupeřův Collision2D objekt vyhledáním Collider2D.gameObject typu zasaženého cíle (nepřítel, Collider2D.collider.tag předmět atd.).

Z OnCollisionEnter2D výše uvedených tří událostí, a OnCollisionExit2D jsou volány jednou za kolizi.

OnCollisionStay2D je volán každý snímek během kolize, ale událost již není volána po uplynutí určité doby od zastavení obou objektů. Je to proto, že se má za to, že vstoupil do stavu spánku, a je považováno za plýtvání zpracováním výpočtu kolizí každého snímku s něčím, co se nehýbe.

Pokud nechcete Rigidbody 2D , aby byl režim spánku, změňte režim spánku parametru na "Nespí".

Po změně kódu nastavte text pro zobrazení informací.

Spusťte hru a pohybujte objektem pomocí klávesnice, abyste se dotkli jiného sprite. Vidíte, že pro každou z nich jsou volány tři funkce.

Mimochodem, pokud se dotknete objektu a pak se přestanete pohybovat, metoda bude volána na OnCollisionStay2D krátkou dobu. Měli byste vidět, že metoda již není volána po OnCollisionStay2D určité době.

To znamená, že jste vstoupili do stavu spánku, ale pokud chcete změnit čas do tohoto spánku, můžete jej změnit výběrem "2D fyziky" v nastavení projektu a zadáním parametru "Doba spánku" v sekundách. Nemůže být nastavena na 0, ale pokud OnCollisionStay2D je nastavena na nekonečně malou, samotná metoda nebude volána.