tömörítse a Tilemap határokat jól sikerült, a játéktábla készen áll a használatra! Erre a 3. részben térünk vissza.
2.rész. Szintadatok
mivel ugyanazt a jelenetet és ugyanazt a játéktáblát akarjuk újra felhasználni, a szintadatokat valahol meg kell őrizni. Egy egyszerű megoldás, hogy egy egyszerű json fájl, amely leírja, hogy minden szinten kell építeni.
fontos megérteni, hogy mit próbálunk elérni, ezért kell néhány szót mondanom a mechanikáról. A játékban vannak olyan tárgyak, amelyek az út mentén mozognak a kezdetektől a végéig (nagyjából úgy, mint a Zuma-ban), és a játékos célja, hogy elpusztítsa mindet. Ebben az oktatóanyagban létrehozzuk ezt az utat, amely minden szinten egyedi lesz.
Oké, vissza a projekthez.
számos módja van, hogyan lehet hozzáférni egy külső adatok egy futásidejű egy script. Itt erőforrások mappákat fogunk használni
hozzunk létre egy új mappát — Files — és egy al-mappa Resources. Ez az a hely, ahol meg akarjuk tartani az adatokat, ezért hozzon létre egy új fájlt-szintek.json és tegye oda.
az oktatói célokra csak két mező lesz az egyes szintek leírására:
szám – egy int egy szint azonosítására
útvonal — a csempe alapú útvonal, amelyet programozottan akarunk létrehozni. Olyan értékek tömbje, ahol az első érték a kezdőpont, az utolsó pedig a végpont.
ezt a fájlt fogom használni. Ne aggódj ezen értékek path, mi jön rá később.
{ "levels": }, { "number": 2, "path": }, { "number": 3, "path": } ] }
hozzunk létre egy másik mappát — szkripteket—, és most végre elindul a kódolás.
az adatokat a kódban lévő fájlból szeretnénk elérni, ezért szükségünk van egy modellosztályra. Itt az ideje, hogy elkészítsük az első szkriptünket — LevelsData
. Ez nem azt jelentette, hogy példányosítani Unity, így MonoBehaviour
és Start
Update
módszerek el kell távolítani. A fenti fájlból láthatjuk, hogy a gyökér elem egy array
szintek, ahol minden szintnek rendelkeznie kell egy int
mezőszámmal és egy int array
mező elérési útjával. Ne felejtsd el feltenni a
megjegyzést.
public class LevelsData { public LevelData levels; public class LevelData { public int number; public int path; } }
szép, most már megvan a fájl és a modell. A következő lépés az, hogy átalakítsuk egymást. Hozzunk létre egy másik szkriptet – GameZone
— és csatoljuk a jelenet GameZone
objektumához. Ezt a szkriptet később felhasználják az egész játéktábla beállításához.
kövesse az egyetlen felelősség elvét hozzunk létre még egy szkriptet — LevelsDataLoader
— amely elvégzi az összes átalakítást. Csatolja a GameZone
objektumhoz is.
public class LevelsDataLoader : MonoBehaviour { private const string LevelsPath = "Levels"; public Dictionary<int, LevelsData.LevelData> ReadLevelsData() { var jsonFile = Resources.Load(LevelsPath, typeof(TextAsset)) as TextAsset; if (jsonFile == null) { throw new ApplicationException("Levels file is not accessible"); } var loadedData = JsonUtility.FromJson<LevelsData>(jsonFile.text); return loadedData.levels.ToDictionary(level => level.number, level => level); } }
Ez az osztály betölti az adatokat, és szótárként adja vissza, ahol a kulcs a szintszám, az adatok pedig maga a szintadatok.
most már elérhetjük az adatokat aGameZone
szkriptben.
public class GameZone : MonoBehaviour { private Dictionary<int, LevelsData.LevelData> _levelsData; private LevelsDataLoader _dataLoader;private void Awake() { _dataLoader = GetComponent<LevelsDataLoader>(); }private void Start() { _levelsData = _dataLoader.ReadLevelsData();Debug.Log(_levelsData.Count + " levels have been stored in the dictionary!"); } }
váltson vissza a Unity — ra, nyomja meg a play gombot és ellenőrizze a konzolt-látnia kell a “3 szint van tárolva a szótárban!”
3.rész. A tábla és az adatok összekapcsolása
Gratulálunk, elérted az oktatóanyag utolsó és legérdekesebb részét. Hogyan kapcsoljuk össze a táblát és az adatokat? Olvass tovább, hogy megtudd!
először is helyezzük el a horizontal
és start_stop
az oktatóanyag első részében létrehozott csempéket az erőforrások mappába a csempe mappa alatt. Ezután adjon hozzá egy új szkriptet – TilesResourcesLoader
— egy statikus segítő osztály, amely futásidejű csempéket tölt be a mappából.
public static class TilesResourcesLoader { private const string PathHorizontal = "horizontal"; private const string StartStop = "start_stop"; public static Tile GetPathHorizontalTile() { return GetTileByName(PathHorizontal); } public static Tile GetStartStopTile() { return GetTileByName(StartStop); } private static Tile GetTileByName(string name) { return (Tile) Resources.Load(name, typeof(Tile)); } }
utolsó lépésként ezeket a csempéket a táblára kell helyezni a jelenet indításakor. Térjünk vissza a GameZone
szkripthez. Először is szimulálnunk kell a szintválasztást, az igazi játékban ez általában akkor történik, amikor a felhasználó megnyom egy szintgombot. Az egyszerűség kedvéért adjunk hozzá egy nyilvános mezőszintet a GameZone
– hez, és változtassuk meg az értékét 1-re a kezdéshez. Először megmutatom a végső szkriptet:
public class GameZone : MonoBehaviour { public int Level; private const int FieldLineSize = 11; private const int FieldTotalTiles = FieldLineSize * FieldLineSize; private Dictionary<int, LevelsData.LevelData> _levelsData; private void Start() { _levelsData = GetComponent<LevelsDataLoader>().ReadLevelsData(); SetupTiles(); } private void SetupTiles() { var baseLevel = GetComponentsInChildren<Tilemap>(); var localTilesPositions = new List<Vector3Int>(FieldTotalTiles); foreach (var pos in baseLevel.cellBounds.allPositionsWithin) { Vector3Int localPlace = new Vector3Int(pos.x, pos.y, pos.z); localTilesPositions.Add(localPlace); } SetupPath(localTilesPositions, baseLevel); } private void SetupPath(List<Vector3Int> localTilesPositions, Tilemap baseLevel) { var path = _levelsData.path; var pathHorizontalTile = TilesResourcesLoader.GetPathHorizontalTile(); var first = path.First(); var last = path.Last(); foreach (var localPosition in localTilesPositions.GetRange(first, Math.Abs(first - last))) { baseLevel.SetTile(localPosition, pathHorizontalTile); } var startStopTile = TilesResourcesLoader.GetStartStopTile(); baseLevel.SetTile(localTilesPositions, startStopTile); baseLevel.SetTile(localTilesPositions, startStopTile); } }
Wow, ez nagyon sok akció! Hadd mutassam meg.
a SetupTiles
módszer először meg kell kap a tilemap magát, mert meg kell tudni, hogy a pozíciók csempe annak érdekében, hogy változtatni. Ennek eléréséhez a tilemap.cellBounds.allPositionsWithin
metódust használjuk, amely visszaadja a csempék összes helyzetét az elsőtől kezdve — az adott konfigurációban ez egy lefelé mutató csempe.
lásd a következő képet, ahol minden szám az indexet képviseli alocalTilesPositions
listában.
számozott tilemap emlékszel az elérési úton használt értékekre Levels.json
? Mint talán már kitalálta, ezek az értékek a tömbben lévő csempék indexei. Most csak annyit kell tennie, hogy van egy cheatsheet kép, amely segít a szintek felépítésében. Ezt használtam a fejlesztés során:
a csúnya számozott tilemap
ebben a példában vízszintes vonalat állítunk be az útvonalon, kérjük, olvassa el a SetupPath
módszert. A legfontosabb rész a következő hurok:
foreach (var localPosition in localTilesPositions.GetRange(first, Math.Abs(first - last))) { baseLevel.SetTile(localPosition, pathHorizontalTile); }
itt ismétlődünk localTilesPositions
hogy megtaláljuk azokat, amelyek ebben az esetben a kívánt csempe vízszintes beállítását teszik lehetővé.
Megjegyzés! GetRange
a metódusnak két paramétere van: index és count.
az útvonal kezdő és végpozícióinak megjelöléséhez a start_stop
csempét használjuk.
itt van a kemény munkánk eredménye:
>
végeredmény
most próbálja meg megváltoztatni a GameZone
szkript szintszám mezőjét 1-ről 2-re vagy 3-ra, és látni fogja, hogy az elérési út megfelelően van betöltve az adott szinthez.
utána