Unity-suli: így készíts inventoryt
Szeretnéd karakteredet egy hatalmas virtuális zsebbel felvértezni, amelybe tárgyakat pakolhatsz? Megmutatjuk, miként hozhatsz létre egy ilyen komponenst.
Egyik legfontosabb eleme a szerep- és túlélőjátékoknak a felszerelésedet tartalmazó inventory, amelyben a gyűjthető elemeket könnyedén tárolhatod, és szükség esetén bármikor hozzájuk is férhetsz. A virtuális hátizsák elkészítése összetett, kihívást jelentő feladat, mert a dizájneri szemléletmódot igénylő felhasználói felület kialakítása mellett bizony a kódolási ismereteidet is meg kell csillogtatnod, hogy egy hibátlanul működő tároló legyen a jutalmad.
Az alábbiakban megtudhatod, miként érdemes belevágnod a tárgylista-fejlesztésbe, a mintaprojektet pedig akár saját szerepjátékod fejlesztése során is hasznosíthatod.
Kellékek összeállítása
A Unity hub megnyitását követően indíts egy új 3D-s projektet, és elsőként navigálj az Asset Store felületére, ahol keresd meg a Standard Assets csomagot, hogy a letöltést és a telepítést követően elérhetővé váljanak az alapvető környezeti elemek, illetve a vezérelhető karakter, ezek nélkülözhetetlenek a projekthez. A beemelt komponensek felhasználásával állíts össze egy jelenetet; tartalmaznia kell egy tetszőlegesen díszített (fákkal, textúrákkal kiegészített) Terrain komponenst, illetve a Characters/ThirdPersonCharacter/Prefabs útvonalon elérhető ThirdPersonController nevű vezérelhető karaktert.
Miután mindezzel végeztél, pozicionáld a kamerát megfelelő nézetbe a karakter mögé, sőt csatold is hozzá, hogy a vezérlés során a megjelenítés kövesse a főszereplő mozgását. Mielőtt nekiállnál kódolni, még muszáj gondoskodnod néhány gyűjthető elemről (mi egy kardot, egy almát és egy üvegcsét választottunk erre a célra), illetve a róluk készült inventorykép alfacsatornás változatáról, továbbá egy teljesen üres, szintén átlátszó képre, amelynek add az empty nevet. Ezzel megtetted a szükséges előkészületeket, vagyis ideje szembenézned a projekt igazi kihívásaival.
Felhasználói felület
Nem fog sokban különbözni a tárgytartó menü létrehozása egy átlagos UI-felület kialakításától, ugyanis mindössze egy panellel, néhány gombbal és pár képpel elérhető a kívánt hatás. Első lépésként a Hierarchy fül alatt található Create menüpont segítségével helyezz egy panelelemet a képernyődre, ezzel voltaképp létrejön egy Canvas munkaterület a hozzátartozó áttetsző panelelemmel. Amennyiben szeretnéd, ezt a hátteret tetszőlegesen díszítheted, de mindenképp módosítsd az Inspector fül alatti Color értéket, amelynek az áttetszőségét kell megszüntetned, illetve a felület Scale-adatait is érdemes a felére csökkentened.
Ezek után egy gomb felhelyezése lesz a feladatod (jobb kattintás a Panelen, majd válaszd a UI/Button opciót), ennek a méretét alakítsd át 80×80-ra, a Source Image-ben található alapértelmezett képét cseréld a UISprite-ra, végül pedig a színét változtasd egy kicsit sötétebbre. Amint ezeket a módosításokat elvégezted, kattints a Hierarchy alatt a gomb melletti háromszögre, és szabadulj meg a hozzátartozó Text komponenstől, ezt ugyanis a példában nem fogod használni. Helyette kell majd egy képkomponens, így a törlés után jöhet egy jobb kattintás a gombra, az ekkor megjelenő menüből válaszd a UI/Image opciót.
Itt szintén állítsd be a képnél azt a méretet, amit korábban már használtál (80×80), és tesztelésként a Source Image opció mellett helyezd el a gombon az almához tartozó képet, így láthattad, miként fog majd megjelenni az összegyűjtött komponens a felületen. Ha ezt ellenőrizted, cseréld az ikont az empty nevű Sprite-ra, és áttérhetsz a fejlesztés következő lépésére.
Kezdődhet a kódolás
Mivel már gyakorlatilag minden készen áll a funkciók élesítésére, elérkezett az idő, hogy elővedd programozói tudásodat. Hozz létre a Hierarchy alatt egy üres GameObjectet (Create/Create Empty), ez az elem fogja majd kezelni a játékhoz tartozó szkriptek egy részét. Miután ezzel megvagy, a Project fül alatti Create használatával hívj életre egy C# szkriptet iventoryElements néven, és nyisd is meg valamilyen szerkesztővel. Az első funkció, amibe életet lehelsz, az a hátizsák gombnyomásra történő megjelenítése és elrejtése lesz.
Ehhez a kód globális változói közé vegyél fel egy canvas nevű elemet (public GameObject canvas;), amely a UI-komponens legkülső tagját kapja majd meg az editorban, és ezáltal a menü láthatóságának szabályozására lesz képes. A Start()-ban kezdeti lépésként deaktiváld ezt a komponenst ( canvas.SetActive(false);), majd az Update()-en belül feltételben vizsgálj egy gombnyomást (if (Input.GetKeyDown("e")){}), amelynek teljesülése esetén ellenőrizd, hogy a Canvas épp milyen igazságértékkel bír, és ennek megfelelően állítsd igazra vagy hamisra a változót (if(!canvas.activeSelf){ canvas.SetActive(true); }else{canvas.SetActive(false);}).
Végül a szkriptet társítsd a játékterület üres objektumához, majd a canvas változóhoz csatold a jelenetben található Canvas elemet, és már tesztelheted is a megjelenítést, illetve az eltüntetést.
Közeli objektumok felvétele
Helyezz el a jelenetben néhány elemet a gyűjthető objektumok közül, és az Inspector nézetükben mindegyik esetén a felül található Tag opció mellett jelenítsd meg a collectible értéket (a legördülő menüben az Add Tag opcióval hozhatsz létre ilyen egyedi jelölőt). Az objektumokhoz az Add Component segítségével csatolj egy Mesh Collidert (amelynek a Convex értékét aktiváld), valamint egy Rigidbodyt.
Ha ezekkel megvagy, térj vissza a kódhoz, és a változók közé helyezz el egyet a játékos karakter felügyeletére (public GameObject player;), majd élesíts egy listát a gyűjtött elemek tárolására (public List<string> collect;), illetve a gombok és a rájuk szánt ikonok változóit is helyezd ide (public List<GameObject> buttons;public Sprite alma, kard, poti;). Következő lépésként az update() mögé hozz létre egy új függvényt a void CheckNearObjects(){} utasítással, ennek magjában gyűjtsd össze a felhasználódtól öt, egységsugárban elhelyezkedő objektumot (Collider[] objects = Physics.OverlapSphere(player.transform.position, 5);), majd egy ciklusban vizsgáld, hogy ezek közül melyeknél található meg a collectible felirat, gombnyomás hatására a nevüket írd a listába, és töröld őket a képernyőről (foreach(Collider objs in objects){if(objs.tag == "collectible"){ if(Input.GetKeyDown("q")){collect.Add(objs.name); Destroy(objs.transform.gameObject);} } }).
Ezek után már csak annyi teendőd maradt, hogy az update felületén meghívd a frissen létrehozott metódusodat, majd egy feltételben vizsgáld az aktuálisan begyűjtött elemek listájának ürességét. Amennyiben ez az elem tartalmaz komponenseket (if(collect.Count!=0){}), akkor egy ciklusban ellenőrizd a hátizsák gombjait, és keresd meg az elsőt, amelyiknek a nézőképe üres (if(buttons[i].transform.GetChild(0).GetComponent<Image>().sprite.name=="empty"){}). Belül már csak annyit kell vizsgálnod, hogy melyik komponenssel egyezik meg a lista aktuális tartalma, és ez alapján beállítanod a megfelelő hátteret (if(collect[0]=="alma"){ buttons[i].transform.GetChild(0).GetComponent<Image>().sprite=alma;}). A csere végrehajtása után töröld az elemet a listából (collect.Remove(collect[0]);) és ugorj ki a ciklusból (break;).
A megfelelő társításokat követően már tesztelheted is a program futását, ahhoz pedig, hogy tényleg látványos eredményt kapj, klónozd bátran a gombokat (de a másolásokat követően ne felejtsd el ezeket az elemeket hozzáadni a szkripted listájához).
Így fejleszd tovább!
A tárgyak gyűjtésének magvalósítása után rengeteg irányba elindulhatsz a fejlesztés során, illetve a felhasználói felület csinosítgatására is hagyhatsz időt magadnak. A PC World Pluson megtalálható példakódok között rálelsz majd egy dropItem nevű állományra, amelynek segítségével a menüelemek gombjait ténylegesen használhatod is, vagyis az összegyűjtött tárgyakat a hátizsákból visszaszórhatod a pályára. Viszonylag egyszerűen megoldhatod azt is, hogy az egyes tárgyak tulajdonságai is megjelenjenek a képernyőn.
Ha szeretnél, akár egy gyorselérési menüt is létrehozhatsz a kijelző alsó részén, ezzel közvetlenül hozzáférhetsz a tárgyakhoz. Végezetül egy címkét elhelyezve csoportosan tárolhatod az azonos elemeket, és ha olyan tárgyakat használsz, amit a karaktered mondjuk elfogyaszthat, akkor egy-két gombnyomással akár az életerő visszatöltése is viszonylag egyszerűen megoldható.