"A lusta programozó a jó programozó" - Mondják. Pedig nem mindig igaz...
Olyan problémába ütköztem a fejlesztés során amit muszáj leírnom, mert a lustaságból adódóan görgettem magam előtt a problémát, kicsit kipofozgattam, megkerültem jobbról is meg balról is, de attól még fennállt. Igazából fel se tűnt volna, ha nem kellett volna tovább fejleszteni a játékot és a v0.0.9-es builddel el is készült volna.
Amikor leteszi a játékos a tornyot akkor elvárja a programtól, hogy rá is tudjon kattintani. Hát itt ütköztem problémákba. Így utólag belegondolva a "massively-broken-shop-button" is ezért olyan bugos. Szintén utólag belegondolva így lett volna eleve logikus felépíteni a játékot, de hát hibáiból tanul az ember...
Szóval laikusoknak mondom, hogy ne aggódjanak, ha ez idáig semmit nem értettek a leírtakból, és ezután se nagyon fognak, de igyekszem emberhez közelire formálni a problémám kifejtését és megoldását.
I. Unity3D:
Nevéből is adódóan nem kifejezetten két dimenziós játékok készítésére specializálódott. Ezt egy ügyes kameratrükkel meg lehet oldani, ha úgy állítjuk be mint a klasszikus X,Y koordinátatengelyt akkor a Z tengely nem látszódik -> meg is van a 2D-s hatás. A Z tengelyen való elhelyezkedéssel lehet rétegezni a textúrákat, melyik melyik felett/alatt legyen, stb.
II. Torony létrehozása:
Amikor kattintunk a képernyőn lévő rácsok egyikébe több minden történik: Megnézi az egér X,Y koordinátáját, kiszámolja belőle, hogy a 10x5-ös rácsozaton belül hova kattintottunk. Ezután arra a pozícióra lerak három objektumot: a tornyunk képét, a tornyunkra rátesz egy DefenseBlock-ot, ami megállítja a lovagokat és egy HitBoxot ami megadja, hogy milyen messze lát el a torony.
III. Lovag létrehozása:
Amikor megnyomjuk az 1-5 gombok valamelyikét akkor egy GreyKnight születik az adott pozícióra. Ez csak egyetlen objektum, egybe van a hitbox, a defenseblock meg a textúra. Ez 1 nagy hiba.
IV. Nyíl létrehozása:
Amikor a GreyKnight hitbox-sza (lényegében maga a lovag) érintkezik akármelyik LandBlock hitbox-szával akkor létrejön egy Arrow objektum. Itt is egyben van mind a három, ez ismét 1 nagy hiba.
V. Hogy néz ki ez a Z tengelyen?
VI. Raycast:
Amikor kattintunk az egérrel akkor egy ún. raycasting jön létre, azaz az egérmutatóból egy végtelen hosszúságú sugár indul el a pálya felé, amíg akadályba nem ütközik. (Másik megoldás lehetett volna, hogy az összes prefabet (prefab = amit klónozni tudunk, majd később módosítani (ősosztályhoz hasonló) ellátom OnMouseEnter/OnMouseExit függvénnyel, de az nem túl rugalmas és a végeredménye ugyan az mint a raycastingnak -> nem oldja meg a problémát, sőt ront rajta) A fenti ábrán látható, hogy a probléma igen sokrétű volt:
- A torony textúrája volt legalul a Z tengelyen
- A DefenseBlock közvetlenül a torony textúrája felett van így a raycast minden esetben ebbe ütközik és nem a toronyba közvetlenül
- A Hitbox lefedi az egész Z tengelyt így minden, a hitbox által lefedett területnél először a sugár a hitboxba ütközik (egyszerűen: ha egymás elé pakoljuk a tornyokat akkor az a terület ameddig a torony látóköre tart "blokkolva" van a hitbox által, így nem "lehet" odakattintani egérrel)
- Ha a Torony textúráját felmozgatom (hitbox fölé) akkor a lövedék textúrája a torony alatt fog elmenni ami nagyon ronda
- Ha a tornyot és a lövedéket is felmozgatom akkor a lovag nem fog érintkezni a lövedékkel, mert nem egy "rétegen" vannak
- Ha a lovagot is felmozgatom akkor meg a lovag nem fog érintkezni a torony hitbox-szával
- (Ha a hitbox-szot is felmozgatom akkor meg ugyan ott vagyunk csak pár "réteggel" feljebb van minden)
VII. Megoldás:
Mindenkinek saját hitbox/defenseblock! "Hogy nem jutott eszedbe? Hát ez triviális!" Persze innentől már nekem is az, de "macerásnak" tartottam (lustaság strikes), viszont tényleg elkerülhetetlen. Lényeg, hogy a LandBlock megmarad külön három objektumnak: textúra/defenseblock/hitbox, a GreyKnight is kap hármat: textúra/defenseblock/hitbox (knightnak még nem szükséges a hitbox, mert csak maga elé lát közvetlenül, de akkor legyünk már előrelátóak és adjuk meg ezt a jövőbeni GreyArcher-nek, aztán max beteszünk egy if feltételt az objektum születésekor, hogy létrehozzon-e neki egyet, avagy sem), míg a lövedék kettőt: textúra/defenseblock. (Persze hívhatnám a hitbox-ot "range box"-nak és a defenseblock-ot "hitbox"-nak, de teljesen mindegy, a felhasználó nem lát ebből semmit, én meg már megszoktam így).
VIII. Konklúzió:
Nem mindig a leglustább megoldás a legjobb! Lehet hogy kezdetben célszerűnek tűnik egybe tartani a dolgokat, de hosszú távon az a jó, ha minden aminek más funkciója van külön létezik, aztán max együtt mozgatjuk őket (ami tény hogy nehezebb, de jobban megéri).
Utolsó kommentek