8. diel - Unity (C #) Android: MenuPart, Eraser, pozadia 2
V minulej lekcii, Unity (C #) Android - MenuPart, Eraser a pozadia , sme pracovali na odstraňovaní už zdolaných prekážok a tiež na nekonečnom opakovaní pozadí. Pridali sme aj ďalšie herné menu.
V dnešnom Unity tutoriálu sa pozrieme na ničenie Stalag a vytvoríme si arkádové levely.
Vylepšenia ničenia
Začnime podstatnejšie funkcií a to ničením Stalag. Ak momentálne do prekážky narazíme, hráč sa zasekne a v podstate sa ďalej nedostaneme. Poďme to napraviť.
Skript kolízie hráča
Skript si vytvoríme na hráčovi, nakoľko s postavou môžeme reagovať na viac kolízií, než len na tú s prekážkou. Skript bude sledovať čoho sa postava dotkla a podľa toho spustíme reakčnej skript na danom objekte, ktorý sa s hráčom zrazil.
PLAYER pridáme PlayerCollisionScript
, ktorý bude zatiaľ len
kontrolovať, či sa s niečím zrazil:
void OnTriggerEnter2D(Collider2D col) { print("kolize"); }
Aby sme zaistili, že nám kolízia bude správne fungovať, pridáme na hráčovi ďalšie circle Collider. Tentokrát ho ale urobíme o máličko väčší a nastavíme ho ako isTrigger. Tým zabezpečíme správne detekovanie.
Ďalej určíme, čo sa stane, podľa typu objektu, ktorého sme sa dotkli.
Reakčný skript pre Stalag
Najskôr si vytvoríme skript pre Stalag. Ako si určite pamätáte, stačí
zvoliť Prefab, ktoré máme uložené, a iba im pridať potrebný skript. To
urobíme tak, že si najprv vytvoríme skript StalagScript
.
Zvolíme všetky Prefab, ktoré chceme, a klikneme na
Add component
. Zobrazí sa nám takéto okienko:
a zvolíme náš skript:
Skript bude obsahovať jednu metódu, ktorá bude reagovať na kolíziu. Ďalej tiež bude mať jednu premennú, kam vložíme particles, ktoré vytvoríme:
Public GameObject parts;
void React()
{
Destroy(gameObject);
}
Samo o sebe by sa zatiaľ samozrejme nič nestalo. Preto metódu musíme
niekde zavolať. To urobíme v našom PlayerCollisionScript
.
Zavolanie pomocou
SendMessage()
Keďže pri kolízii máme prístup k nášmu objektu, sme schopní k nemu pristúpiť a poslať mu správu, čo má urobiť:
void OnCollisionEnter2D(Collision2D col) { if(col.collider.CompareTag("Stalag")) { GameObject stalag = col.collider.gameObject; stalag.SendMessage("React"); } }
Metóda SendMessage()
nám na danom objekte zavolá metódu s
názvom, ktorý sme napísali do parametra.
Metódu musíme zapísať ako textový reťazec, tak si musíme dať pozor, aby sme názov metódy napísali presne. Tento spôsob odporúčam používať len pokiaľ je na danom objekte málo skriptov a metód, pri väčšom množstve to môže mať vplyv na výkon.
Zavolanie pomocou
GetComponent()
Druhá možnosť je nastaviť metódu React()
ako
public
a pri kolízii ju zavolať pomocou
GetComponent()
:
void OnCollisionEnter2D(Collision2D col) { if(col.collider.CompareTag("Stalag")) { GameObject stalag = col.collider.gameObject; stalag.GetComponent<StalagScript>().React() } }
V našom prípade však perfektne stačí SendMessage()
. Teraz,
keby sme hru spustili a narazili do Stalag, zmizne. Je to presne to, čo sme
chceli, ale nevyzerá to veľmi pekne. Chcelo by to nejaký efekt.
Efekt zničenie
Pridáme si teda nejaké to rozpadnutie. Vytvoríme si pre to nový
GameObject, pomenujeme si ho ParticlesIce
, a pridáme si naň
Particle System:
Nastavíme niekoľko vlastností. Gravity Multiplier zväčšíme na
0.3
. Vidíme, ako naše čiastočky padajú. Ďalej chceme, aby sa
efekt prehral iba raz. Nájdeme si Looping a zrušíme ho. Duration nastavíme
na 0.5
. Ďalej v Emission nastavíme Rate na 20
:
To už vyzerá celkom slušne! Lenže stále máme obyčajná kolieska a chceme, aby sa nám generoval nejaký pekný tvar. Tento tvar zas nájdete nižšie na stiahnutie. Ak si však chcete vytvoriť vlastné dielo a alebo nájsť iný, pokojne môžete.
Materiál
Aby sme Particle Systémom mohli generovať vlastné grafické prvky, musíme
si najskôr vytvoriť nový Material. Klasicky klikneme pravým do
Assets
:
Ten pomenujeme IceMat
a nastavíme mu náš kus ľadu. Shader
nastavíme na LegacyShader -> Particles -> Additive:
Tento materiál v Particle Systéme vložíme do Renderer a Material. Z objektu vytvoríme prefab:
Teraz na vše Prefab Stalag môžeme vidieť jedno voľné miestečko u
StalagScript
. Na toto miesto vložíme náš
ParticleIce
objekt. Vďaka tomu máme prístup k tomuto objekt cez
náš skript.
Otvoríme si StalagScript
v ktorom, ako teda zničíme náš
Stalag, vytvoríme efekt:
Destroy(Instantiate(parts, transform.position, Quaternion.identity), 2);
Vyzerá to zložito, ale vlastne ani nie je. Hovoríme, že chceme zničiť
objekt, ktorý sa vytvorí, a chceme ho zničiť za dve sekundy od prevedenia
tejto riadky. Pomocou Quaterion.identity
zaistíme, aby sa
vygenerovaný objekt neotočil v nejakej osi.
Výsledný StalagScript
vyzerá takto:
void React() { Destroy(Instantiate(parts, transform.position, Quaternion.identity), 2); Destroy(gameObject); }
V podstate to je všetko ohľadom ničenia Stalag. Teraz sa môžeme pustiť do vytvorenia niekoľkých levelov do nášho Arcade módu.
Nové levely
Pre uľahčenie práce si môžeme len skopírovať všetky objekty v scéne,
na ktorej momentálne sme. Objekty si všetky označíme a skopírujeme
klasickým Ctrl + C. Vytvoríme si novú scénu, do ktorej
všetky objekty pomocou Ctrl + V vložíme. Najprv
zmažeme StartingObject
, ktorý nám tu k ničomu nebude. Generuje
totiž Stalag a to my v Arcade nechceme, pretože si levely naklikáte sami.
Na skúšku si vytvoríme jednoduchý level, kde hráč preletí pár prekážkami, kde sa bude nachádzať koniec. Pre tento účel som vám vyrobil tiež nejakú grafiku, aby ste sa nemuseli zdržiavať hľadaním na Google a mohli zatiaľ bezstarostne pokračovať v tutoriálu.
Sprite
Sprite si roztiahneme:
Na tento sprite si vložíme Collider. Collider nastavíme na Trigger a
pridáme mu EndScript
. Objekt si tiež pomenujeme
endLine
. Objekt bude vo finále vyzerať takto:
Budeme zase strážiť, či sa tohto objektu dotkol hráč:
bool isEnd = false; void OnTriggerEnter2D(Collider2D col) { if(col.CompareTag("Player")) { isEnd = true; Time.timeScale = 0; } }
Ak sa teda hráč dotkne cieľa, nastavíme Time.timeScale
na
0
, čo nám stopne hru.
Menu
Síce sme si v minulých lekciách hovorili, že nebudeme používať programovacie spôsob robenie menu, ale urobme výnimku, pretože sa to v tomto prípade celkom hodí:
void OnGUI() { if (isEnd) { if (GUILayout.Button("Menu")) { Time.timeScale = 1; SceneManager.LoadScene("Menu2"); } if (GUILayout.Button("Next level")) { Time.timeScale = 1; string currLevelId = Application.loadedLevelName; currLevelId = Application.loadedLevelName.Substring(currLevelId.Length - 1); print("Aktualni level: " + currLevelId); int currLevelInt = int.Parse(currLevelId); currLevelInt++; string newLevelName = "Level0" + currLevelInt; SceneManager.LoadScene(newLevelName); } if (GUILayout.Button("Restart")) { Time.timeScale = 1; SceneManager.LoadScene(Application.loadedLevelName); } } }
Pri načítaní menu si nesmieme zabudnúť dať pozor na názov menu, prípadne na index. Inak si myslím, že ohľadom menu nie je nutné nič vysvetľovať, pretože sme si všetko už vysvetlili v predchádzajúcich lekciách o menu.
Možno vás zaujal kód:
string currLevelId = Application.loadedLevelName; currLevelId = Application.loadedLevelName.Substring(currLevelId.Length - 1);
Levely si budeme pomenovávať Level0x
, kde x
je
číslo nášho levelu. Týmto kódom si zistíme index v názve nášho levelu,
ktorý si ďalej prevedieme na typ int
a využijeme ho na
načítanie nasledujúcich levelov. Síce môžeme spúšťať levely len podľa
indexu scenára, ale to by sme museli mať levely zoradené. Takto môžeme mať
levely rozhádzané ako chceme a stále je dokážeme spustiť len vďaka
názvu.
Keď teraz s hráčom preletíme cieľom, objaví sa nám menu v ľavej hornej časti obrazovky:
Zatiaľ to necháme takto a vylepšíme ho v budúcnosti. Tiež niekedy dlhšie ošetríme prípad, kedy hráč pokorí posledný arkádový level.
Aby nám fungovalo tlačidlo "Menu", musíme si priradiť index a alebo názov menu.
Vo finále si vytvoríme druhý level, pomenujeme si ho
Level02
:
A nezabudneme ho pridať v Build Settings.
To pre dnešné tutoriál bude všetko. Dúfam, že ste sa dozvedeli niečo nové:-)
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 391x (11.74 kB)