Řešení kolizí pomocí standardní fyziky (2D)
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 2D
Box 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.