16# 1942 Classic 3.
V minulé lekci jsme dokončili pohyb a střelbu hráče. Nyní by jsme měli udělat trasu pohybu pro nepřátele. Budeme to dělat pomocí Waypoints, na scéně budeme mít množství bodů, kterými budou nepřátelé procházet.
Začneme tím, že si vytvoříme prázdný objekt Path(0) (cesta) a uvnitř ní si dáme další prázdný objekt Waypoint(0) (Bod cesty). Nula je za tím, protože předpokládáme více cest a více bodů a v programování vždy počítáme od nuly. Doporučuji vždy při vytváření resetovat polohu prázdného objektu X0, Y0, Z0.
Ve hře nebudeme chtít, aby byly body vidět, co ale je pro nás problém je, že prázdné objekty nejsou vidět ani ve scéně pokud nejsou označené. Aby jsme prázdné objekty viděli, musíme jim přiřadit ikonu v inspektoru. V našem případe chceme vidět Waypointy.
Nyní ve scéně by jste měli vidět červený diamant, v místě kde máme prázdný objekt. Waypoints budeme potřebovat víc. Když jej v hierarchii označíte a dáte CTRL + D (Duplikovat), měli by se vám vytvářet další číslované waypointy. Na začátek si udělejte pouze tři a poskládejte si z nich krátkou trasu přes obrazovku.
Nyní musíme jednotlivé body připojit ke scriptu. K tomu jsme předtím používali Array. Ta se hodí na spoustu věcí, ale má statickou velikost, kterou musíme předem nastavit. My budeme chtít jedním scriptem zpracovávat více cest, s různou délkou / počtem bodů. K tomu se nám bude hodit List. V mnoha ohledech je stejný jako Array, jen není třeba nastavit velikost. V budoucnu, pokud by jsme se rozhodovali jestli udělat Array s pár tisíci vstupy nebo List s pár tisíci vstupy, je lepší udělat Array protože je v hodnější pro optimalizaci. To nás ale v tomto případě netrápí.
Nyní si vezmeme v Assets -> Prefabs nepřítele (Enemy) a přidáme mu script. Ten můžeme pojmenovat EmenyPath. Script si otevřeme ve Visual Studiu a začneme upravovat.
Jako první si vytvoříme serializovanou proměnnou waypoints. Ta bude fungovat jako list a uložíme do ni polohu bodů. Polohu najdeme pod transform a tak bude typ proměnné transform.
V budoucnu budeme cesty plnit pomocí scriptu, ale na začátek budeme testovat alespoň nějaký pohyb. A tak se přepneme do Unity, Vybereme si Enemy co máme v hierarchii, nastavíme velikost Waypoints na 3, zamkneme si inspektora malým zámečkem v pravém horním rohu.
Když máme zamčeného inspektora, můžeme přetáhnout jednotlivé body z hierarchie do Waypoints.
Nyní máme všechny 3 body na obrazovce, co ale chceme udělat je, aby náš nepřítel začal na bodu 1, který ve finální verzi bude mimo obrazovku, přesunul se přes všechny body a když dojede k poslednímu, aby se zničil. Jde o to, aby ve hře nezabíral místo a aby jsme po půl hodině hraní neměli mimo obrazovku stovky nepřátel co již nebudeme potřebovat. K tomu budeme potřebovat funkci MoveTowards.
Jak náš script bude fungovat, napřed budeme zjišťovat jestli už nejsme náhodou na posledním bodu – pokud ano budeme se chtít zničit – pokud ne budeme se chtít posunout o kousek dál. Uděláme kontrolu jestli jsme již na další bodu – pokud ano zvýšíme číslo cílového bodu – pokud ne nic neděláme. To bude probíhat každý snímek.
Začneme založením proměnných. Jedna bude hlídat na kolikátém Waypointu jsme, druhý bude serializovaná a ta bude určovat rychlost pohybu ( použijeme ji ve funkci MoveTowards.
Jako první část scriptu, přesuneme se zapnutím nepřítele na bod 0. Přesouvání na jednotlivé body jsme již dělali několikrát, začátek je stejný transform.position, které přiřadíme pozici prvního bodu v našem seznamu waypoints.
Když máme připraveného nepřítele na bodu nula, začneme psát jeho pohyb do update(). Jako první podmínka, jestli je se ještě kam pohybovat, lépe řečeno jestli aktuální waypointIndex je menší než počet záznamů v listu (count) mínus 1. Mínus jedna proto, že počet záznamů počítáme od 1 a index je od 0.
Pro posunutí pomocí Vector2.MoveTowards musíme použít 3 hodnoty. Aktuální pozici (transform.position), pozici bodu kam se chceme přesunout a rychlost jakou se chceme přesouvat během jednoho snímku. Aktuální pozici nemusíme řešit, ta je opravdu jednoduchá, ostatní ne tolik. Na oboje si založíme proměnou. Jedna bude targetPosition a druhá bude movementThisFrame. O pohybu jsme již mluvili když jsme vytvářeli pohyb lodi, a tenkrát jsme do kódu přidávali Time.deltiTime, kterým rušíme výhody/nevýhody rychlejších počítačů.
Pro získání pozice dalšího bodu, vezme list waypoints, z něj waypoint, ke kterému jdeme (waypointIndex) a z toho vezmeme polohu (transform.position).
Nyní samotný posun. Budeme měnit aktuální polohu nepřítele (transform.position), pomocí Vector2.MoveTowards. Ta požaduje napřed aktuální polohu, pak cílovou polohu a nakonec rychlost.
Nyní musíme zjistit, jestli náhodou již nejsme na další bodu a nemusíme se začít posouvat směrem k dalšímu bodu. Proto se zeptáme jestli (if) naše poloha (tranform.position) není stejná (==) jako poloha cílového bodu (targetPosition). Pokud ano, posuneme se v seznamu cílových bodů o jedno dál (waypointIndex++).
Poslední část, zničení nepřítele neboli Destroy(gameObject);.
Ještě jako poslední drobný refactoring, protože Update určitě toho bude obsahovat ví a takhle je to minimálně nepraktické.
Hotovo. Stačí uložit, přepnout do unity a vyzkoušet.
Když už se nám nepřítel hýbe, uděláme v další lekci z jednoho pohybu vlnu nepřátel.
0 Comments