Unity procedural TileMap generation without creating gameobject per tile

Hledal jsem internet, abych našel efektivní způsob, jak vytvořit procedurální tilemap bez vytvoření GameObject na dlaždici. Všechny návody TileMap, které jsem našel, vytvářejí dlaždice vytvořením stovek GameObjects. Hierarchie v Unity se tedy neočekávaně rozšiřuje.

Jsem si docela jistý, že to není „správný“ způsob, jak to udělat. Zvláště poté, co jsem viděl nové nástroje Unity 2D, které podporují tilemapy. Unity to udělal, dlaždice můžete vytvářet v „jednom“ herním objektu, ne pro každou dlaždici.

Takže, jak to udělám správným a efektivním způsobem?

Komentáře

  • Vy ‚ jste to zveřejnili na dvou webech SE. Vyberte jeden.
  • Co ‚ Je vaším konkrétním zájmem vytvářet velké množství GameObjects? Pokud je to ‚ jen nepořádek v hierarchii, existují jednoduché způsoby, jak to napravit. Jednota by mělo podobné dlaždice kombinovat do jedné dávky, takže ‚ je nepravděpodobné, že by to byl hlavní trest za volání losování, kdybyste to dělali tímto způsobem. Minimalizace dlaždic mimo obrazovku a čas strávený funkcemi aktualizace dlaždic jsou také řešitelné problémy. Vyprofilovali jste svou hru a identifikovali konkrétní c překážkou ‚ snažíte se to vyřešit?
  • @DMGregory No, když uvažujeme o 100 * 100 mapě na obrazovce (pokud předpokládáme, že jsme oddálili, abychom viděli celou mapa), na scéně vytvoří 10 000 herních objektů. To také znamená 10 000 nezbytných transformačních komponent. Ani ‚ nevím, jestli jednota může podporovat 10 000 objektů v okně hieararchie. Vím, že to po několika stech zamrzne.

Odpovědět

Tady si vím:

Možnost 1. GameObject na dlaždici. V určitých případech to není úplně hrozné. V závislosti na vašich potřebách by to mohlo fungovat … dost dobře.

Možnost 2. Jediný quad nebo letadlo odkazující na texturu, kterou vytvoříte za běhu. v zásadě použijte svoji texturu atlasu dlaždic k „vymalování“ mapy jako jedné nové textury. V závislosti na velikosti vaší mapy samozřejmě budete chtít mít několik čtyřúhelníků / letadel, z nichž každá představuje části vaší mapy.

Možnost 3. Vytvořte si vlastní síť. To by více než pravděpodobně byla metoda, která se vám po implementaci bude líbit nejvíce. „Poskytne vám spoustu flexibility a pravděpodobně nejvyšší výkon. V zásadě byste vytvořili kvadrant na dlaždici a každý vrchol UV nastavili tak, aby mapoval na dlaždice v atlasu dlaždic.

Možnost 2, I“ Navrhuji sledovat tuto sérii videí od quill18creates: Série výukových programů 3D TileMap od quill18creates

U možnosti 3 je to můj kód s vylepšeními, takže to nemusí být dokonalé:

//For this, your GameObject this script is attached to would have a //Transform Component, a Mesh Filter Component, and a Mesh Renderer //component. You will also need to assign your texture atlas / material //to it. void Start() { meshFilter = GetComponent<MeshFilter>(); BuildMesh(); } public void BuildMesh() { int numTiles = mapSizeX * mapSizeY; int numTriangles = numTiles * 6; int numVerts = numTiles * 4; Vector3[] vertices = new Vector3[numVerts]; UVArray = new Vector2[numVerts]; int x, y, iVertCount = 0; for (x = 0; x < mapSizeX; x++) { for (y = 0; y < mapSizeY; y++) { vertices[iVertCount + 0] = new Vector3(x, y, 0); vertices[iVertCount + 1] = new Vector3(x + 1, y, 0); vertices[iVertCount + 2] = new Vector3(x + 1, y + 1, 0); vertices[iVertCount + 3] = new Vector3(x, y + 1, 0); iVertCount += 4; } } int[] triangles = new int[numTriangles]; int iIndexCount = 0; iVertCount = 0; for (int i = 0; i < numTiles; i++) { triangles[iIndexCount + 0] += (iVertCount + 0); triangles[iIndexCount + 1] += (iVertCount + 1); triangles[iIndexCount + 2] += (iVertCount + 2); triangles[iIndexCount + 3] += (iVertCount + 0); triangles[iIndexCount + 4] += (iVertCount + 2); triangles[iIndexCount + 5] += (iVertCount + 3); iVertCount += 4; iIndexCount += 6; } mesh = new Mesh(); //mesh.MarkDynamic(); if you intend to change the vertices a lot, this will help. mesh.vertices = vertices; mesh.triangles = triangles; meshFilter.mesh = mesh; UpdateMesh(); //I put this in a separate method for my own purposes. } //Note, the example UV entries I have are assuming a tile atlas //with 16 total tiles in a 4x4 grid. public void UpdateMesh() { int iVertCount = 0; for (int x = 0; x < mapSizeX; x++) { for (int y = 0; y < mapSizeY; y++) { UVArray[iVertCount + 0] = new Vector2(0, 0); //Top left of tile in atlas UVArray[iVertCount + 1] = new Vector2(.25f, 0); //Top right of tile in atlas UVArray[iVertCount + 2] = new Vector2(.25f, .25f); //Bottom right of tile in atlas UVArray[iVertCount + 3] = new Vector2(0, .25f); //Bottom left of tile in atlas iVertCount += 4; } } meshFilter.mesh.uv = UVArray; } 

Komentáře

  • Vaše odpovědi mi pomohly zpět v dnů. Nyní se dívám na své staré otázky a ‚ jsem si uvědomil, že jsem ‚ tuto odpověď nikdy nekontroloval jako přijatou. Omlouváme se za věčné pozdní schválení ^ ^ Děkujeme za odpověď.

Odpověď

Jak jste (myslím ), o kterém se zmiňuje, cestovní plán Unity má plány pro editor tilemap. Těším se na něj, protože právě teď je trochu matoucí, jak postupovat.

Mezitím nejlepší přístup „Vidím, je vytvořit si mapu v dlaždici a poté ji pomocí X-UniTMX importovat do Unity. Je zřejmé, že to není generování procedur; domnívám se, že k vytvoření sítě použijete stejnou techniku, jakou používá X-UniTMX.

Odpovědět

Mohli byste mít dlaždice vytvořené hlouběji v hierarchii, zavřít tuto složku a neobtěžovat se. Můžete také skrýt své herní objekty z hierarchie `myTile.hideFlags = HideFlags. HideInHierarchy „si nejste jisti, jaký výkon by se získal.

Zobrazování textur o rozměrech 100 x 100 na obrazovce není nikdy dobrý nápad. Kreslení textur je těžší než kreslení polygonů. Pokud potřebujete oddálit tak daleko, bude vám lépe s většími texturami. Totéž platí pro přiblížení, neměli byste kreslit textury, které se kreslit nepotřebují.

To, co obvykle dělám (nejsem člověk z Unity), je vytvoření třídy pro mapu a použití dvourozměrné pole pro uložení všech vašich dlaždic. Toto pole může být jednoduše z ints nebo třídy Tile s několika ints, které odkazují na vaše textury, typ dlaždice, objekty atd. Pak by se to nakreslilo takto:

for (int y = 0; y < mapHeight; y++) { for(int x = 0; x < mapHeight; x++) { Graphics.DrawTexture(new Rect(x * tileWidth, y * tileHeight, tileWidth, tileHeigt), tileTexture); } } 

Metoda kreslení, kterou používám, se zdá být pro kreslení grafického uživatelského rozhraní, ale může být pro daný úkol naprosto vhodná. V opačném případě musíte kopat do správce sprite a najít způsob který pracuje s touto metodou.

Můžete použít slovník pro referenci textury, jako int 1 ve vaší třídě dlaždic odkazuje na nějakou texturu a int 2 odkazuje na jinou.Na řádku, kterou kreslíte svou texturu, byste pomocí svého slovníku dali správný objekt textury. Tímto způsobem by neměl vytvářet GameObject, a tedy nevytvářet všechny zbytečné režijní náklady.

Totéž můžete udělat pro téměř všechno, co nepotřebuje úroveň kontroly nad GameObject. Nezapomeňte, že tímto způsobem nakreslí každou dlaždici vaší mapy, nejpravděpodobněji automaticky nezruší objekty, jako si myslím, že jednota dělá s herními objekty. Ale jen kreslení toho, co musí být na obrazovce, je velmi snadné. Znáte velikost obrazovky / výřezu, polohu kamery a velikost dlaždice. Nějaká jednoduchá matematika by měla nakreslit přesně to, co je potřeba.

Jednota je přesto 3D engine. Podporuje pouze 2D ve 3D. Ale v podstatě můžete udělat totéž pro quads / meshes s texturami a ortografická kamera. Pouhé kreslení těchto potřebných sítí je docela levné.

Odpověď

Jako někdo, kdo pracuje na projektu založeném na voxel / block „Nemohu si pomoct, ale přemýšlet jen o použití stejného přístupu, pouze ve 2D. Můžete procedurálně vytvořit mřížku podobnou mřížce a přiřadit správné souřadnice vizuálních dlaždic v atlasu textury UV kanálu. Ve 3D musíte udělat mnohem více práce než to, aby měl vysoký výkon, ale ve 2D je to velmi pravděpodobné.

Odpověď

LeanPool můžete vždy použít . Je to aktivum zdarma v obchodě s aktivy. Je to sdružování objektů za vás. Poté můžete udělat jednoduchý vyřazovací systém kolem pohledu kamer, který při vstupu / výstupu z pohledu kamery zobrazí / zobrazí kostkové objekty. Nejsem si jistý, jak velká bude vaše tilemapa, ale Unity zvládne docela dost herních objektů. LeanPool má srovnávací scény v Unity, kde můžete založit / de založit tisíc objektů s kolizními komponentami boxu a myslím, že možná i renderovací komponentu na každé z nich a dělá to velmi rychle.

https://gamedevacademy.org/how-to-script-a-2d-tile-map-in-unity3d/

Zde je odkaz, který vám ukáže příklad použití LeanPool s tilemapou.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *