Riešenie kolízií so štandardnou fyzikou (2D)
Prostredie overovania
- Windows
-
- Windows 11
- Editor jednoty
-
- 2021.3.3f1
- Vstupný systémový balík
-
- 1.3.0
Predpoklady pre tento tip
Nasledujúce nastavenia boli vykonané vopred ako predpoklad pre popis tohto tipu.
Najskôr
Tento tip umiestni dva objekty, aby ste mohli implementovať správanie manipulácie s jedným objektom a pomocou štandardnej fyziky Unity tlačiť druhý, keď príde do kontaktu s druhým.
Mimochodom, väčšina nastavení je rovnaká ako postup opísaný v predchádzajúcom článku "Určenie, či sa objekty navzájom zrážajú (2D)".
Príprava
Postup je tu takmer rovnaký ako predchádzajúce tipy , takže poďme plynule plynúť.
Po vytvorení projektu pripravte dva sprite obrázky, ktoré budú objektmi, a pridajte ich. Názvy sú "UnityTips" a "UnityTips_2".
Pridajte dva súbory s obrázkami tak, že ich vložíte do zobrazenia.
Pridajte skript na presun ľavého objektu pomocou klávesnice. Názov Player
skriptu 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);
}
}
}
Priložte k objektu, na ktorom chcete spustiť skript.
Spustite hru a skontrolujte, či funguje s kurzorovými klávesmi na klávesnici.
Nakoniec umiestnite textový objekt, aby sa zobrazil stav detekcie kolízie.
Názov TextState
objektu je .
Nastavenia riešenia kolízií
Odtiaľto môžete nakonfigurovať nastavenia týkajúce sa kolízií.
Najprv vyberte objekt, ktorý chcete presunúť, "UnityTips" a kliknite na "Pridať komponent" od inšpektora.
Vyberte zo Physics 2D
zoznamu. Physics
je 3D objekt, takže sa nenechajte pomýliť.
Physics 2D
Box Collider 2D
Vyberte si z . Keďže tento sprit je obdĺžnikový, vyberie sa položka Box, ale ak má napríklad tvar kruhu, vyberte iné tvary, napríklad Kruh.
Minule som chcel získať informácie len o tom, či som to trafil alebo nie, tak som zaškrtol "Make it trigger", ale tentoraz nebudem. To umožňuje riešenie kolízií vo fyzike.
Rigidbody 2D
Potom pridajte komponenty súboru . Môžete ho pridať z "Fyzika 2D -> Rigidbody 2D".
Rigidbody
poskytuje objektu fyzikálne informácieCollider
a môže tiež určiť kolízie s objektmi, ktoré majú .
Nastavte gravitačnú stupnicu na 0, aby ste zabránili voľnému pádu nižšie.
Podobne pridajte komponent k inému objektu "UnityTips_2" na označenie Box Collider 2D
prístupov.
Okrem toho je tentoraz potrebné pohybovať sa silou súpera,Rigidbody 2D
takže pridajte . Stupnica gravitácie by mala byť 0.
To je všetko. V súčasnosti nie je potrebný žiadny program. Spustite hru a skúste sa dotknúť iného objektu.
Myslím si, že môžete potvrdiť, že ak súpera takto zatlačíte, súper sa bude správať, akoby bol tlačený. Je veľmi ľahké použiť fyziku štandardnej funkcie, pretože nie je potrebný žiadny program.
Zabránenie otáčaniu objektov
Môžete vidieť, keď sa ho dotknete, ale ak sa bod zásahu čo i len mierne posunie, každý objekt sa otočí. Ako hra sa často stáva neprirodzenou, takže ju musíte nastaviť tak, aby sa neotáčala.
Rigidbody 2D
Komponent má položku s názvom "Pevná rotácia" v časti "Obmedzenia", preto skontrolujte Z.
Teraz môžete pracovať tak, aby sa neotáčal. Skúste ju nastaviť na dva objekty a spustiť hru, aby ste ju skontrolovali.
Myslím, že si môžete byť istí, že sa neotáča bez ohľadu na to, z akého uhla ho tlačíte.
Urobte niečo, keď sa objekty navzájom zasiahnu
Môžete napríklad implementovať guľku, ktorá zasiahne nepriateľa a zároveň tlačí súpera a zároveň znižuje zdravie nepriateľa. Je to rovnaké ako predchádzajúce tipy , pretože udalosť nastane, takže sa s ňou môžete vysporiadať.
Player
Otvorte skript a pridajte každé pole a metódu nasledujúcim spôsobom:
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}";
}
}
Keďže chceme zobraziť informácie o tom, či bol alebo nebol zasiahnutý, umožníme ho zobraziť v textovom objekte nasledovne.
<summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;
Proces detekcie kolízie je opísaný nasledovne.
<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}";
}
Podobne ako predchádzajúce tipy------, ale názov metódy je teraz "OnCollision------2D" namiesto "OnTrigger2D".
Rigidbody 2D
Každá z vyššie uvedených udalostí nastane, keď sa objekt, ktorý sa zrazí s iným objektom Collider 2D
, ktorý má .
To vám umožní určiť a spracovať, či je to správne alebo nie.
Existujú tri udalosti, z ktorých každá sa nazýva v nasledujúcom čase.
OnCollisionEnter2D | Keď do seba objekty narazia |
OnCollisionStay2D | Zatiaľ čo objekty do seba narážajú |
OnCollisionExit2D | Keď objekty opustia kolízny stav |
V oboch prípadoch objekt súpera dostane objekt súpera ako argument, takže objekt súpera Collision2D
môžete získať vyhľadaním Collider2D.gameObject
typu zasiahnutého cieľa (nepriateľ, Collider2D.collider.tag
predmet atď.).
Z OnCollisionEnter2D
vyššie uvedených troch udalostí a OnCollisionExit2D
nazývajú sa raz za kolíziu.
OnCollisionStay2D
sa nazýva každý rám počas kolízie, ale udalosť sa už nevolá po uplynutí určitého času, pretože oba objekty sa zastavili.
Je to preto, že sa považuje za vstup do stavu spánku a výpočet kolízií každého rámu s niečím, čo sa nepohybuje, sa považuje za plytvanie spracovaním.
Ak nechcete, aby spal, zmeňte Rigidbody 2D
režim spánku parametra na "Nespať".
Po zmene kódu nastavte text na zobrazovanie informácií.
Spustite hru a presuňte objekt pomocou klávesnice, aby ste sa dotkli iného sprite. Môžete vidieť, že pre každú z nich sú potrebné tri funkcie.
Mimochodom, ak sa dotknete objektu a potom sa prestanete pohybovať, metóda sa na krátky čas vyvolá OnCollisionStay2D
.
Mali by ste byť schopní vidieť, že metóda sa po určitom čase už nenazýva OnCollisionStay2D
.
Znamená to, že ste vstúpili do stavu spánku, ale ak chcete zmeniť čas, kým nevstúpite do tohto spánku, môžete ho zmeniť výberom položky "2D fyzika" z nastavení projektu a zadaním parametra "Čas spánku" v sekundách.
Nedá sa nastaviť na 0, ale ak OnCollisionStay2D
je nastavená na nekonečne malú, samotná metóda sa nebude volať.