Unity eljárási TileMap generálás anélkül, hogy játékobjektumot hozna létre csempénként

Az interneten kerestem, hogy hatékony eljárási módot hozzak létre egy eljárási csempetérkép létrehozásához anélkül, hogy csempénként létrehoznánk a GameObject-et. Az általam talált TileMap oktatóanyagok több száz GameObjects létrehozásával hoznak létre csempéket. Így az Unity hierarchiája váratlanul bővül.

Biztos vagyok benne, hogy ez nem a megfelelő módszer. Különösen azután láttam az új Unity 2D eszközöket, amelyek támogatják a térképeket. A Unity ezt tette, létrehozhat csempéket “egy” játékobjektumban, nem minden egyes csempéhez.

Szóval, hogyan tudom ezt megfelelő és hatékony módon csinálni?

Megjegyzések

  • ‘ ezt két SE webhelyre tette közzé. Válasszon egyet.
  • Mi ‘ neked különös gondod van a nagyszámú GameObjects létrehozásával? Ha ‘ csak a hierarchia rendetlensége van, akkor ennek megoldására egyszerű módszerek vannak. >

s kötegelésnek amúgy is hasonló tételeket kell egyesítenie egyetlen tételben, így ‘ nem valószínű, hogy komoly húzási felhívást jelentene az ilyesmi. A cserépfrissítési funkciókban eltöltött idő szintén megoldható probléma. Profilozta a játékát és azonosított egy specifikációt c szűk keresztmetszet ‘ megpróbálja megoldani?

  • @DMGregory Nos, ha a képernyőn 100 * 100-as térképre gondolunk (ha feltételezzük, hogy kicsinyítettük, hogy teljes egészében lássuk térkép), 10.000 játékobjektum lesz a helyszínen. Ez 10 000 felesleges transzformációs komponenst is jelent. Nem is tudom, ‘ még azt sem, hogy az egység képes-e támogatni a 10.000 objektumot a hieararchia ablakban. Tudom, hogy pár száz után megdermed.
  • Válasz

    Itt tudok róla:

    1. lehetőség: GameObject csempénként. Bizonyos esetekben nem teljesen szörnyű. Az Ön igényeitől függően elég jól működhet.

    2. opció. Egy négyes vagy sík, amely a futás közben létrehozott textúrára hivatkozik. lényegében a csempe atlasz textúrájával használja a térkép “új festékként” történő festését. Természetesen a térkép méretétől függően érdemes több négyest / síkot használni, amelyek mindegyike a térkép egyes részeit képviseli.

    3. lehetőség: Hozzon létre saját hálót. Ez valószínűleg többnyire az a módszer, amelyet a legegyszerűbben a megvalósítás után fog szeretni. “Rengeteg rugalmasságot és valószínűleg a legnagyobb teljesítményt nyújt. Lényegében létrehozna egy négyzetet csempénként, és minden csúcsot UV-re állítaná, hogy a csempék atlaszában lévő csempékhez társuljon.

    A 2. opciónál I” azt javasoljuk, hogy nézze meg ezt a videósort: quill18creates: 3D TileMap oktatósorozat, írta: quill18creates

    A 3. opcióhoz ez az én kódom, csípéssel, így nem biztos, hogy tökéletes:

    //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; } 

    Megjegyzések

    • Válaszai segítettek visszajutni a napok. Most átnézem régi kérdéseimet, és ‘ rájöttem, hogy soha ‘ soha nem ellenőriztem ezt a választ. Elnézést az örökkévalóság késői jóváhagyásért ^^ Köszönöm a választ.

    Válasz

    Amint Ön (szerintem ) utalt, a Unity ütemterve tervezi a tilemap szerkesztőt. Nagyon várom, mert jelenleg ez kevéssé zavaró, hogyan tovább.

    Időközben a legjobb megközelítés I “Azt látom, hogy a térképedet a Tiledben készíted el, majd az X-UniTMX segítségével importálod a Unity-be. Nyilvánvaló, hogy ez nem eljárásjogi előállítás; azt képzelném, hogy ugyanazt a technikát használja, mint amelyet az X-UniTMX használ a háló létrehozására.

    Válasz

    Lehet, hogy csak a hierarchiában mélyebben létrehozott csempéket akarja bezárni, és bezárja a mappát, és ez nem zavarja. Amit tehet, az is, hogy elrejti a játékobjektumait a `myTile.hideFlags = HideFlags hierarchia elől. A HideInHierarchy “nem biztos abban, hogy mekkora teljesítmény érhető el.

    A 100×100 méretű textúrák megjelenítése a képernyőn soha nem jó ötlet, ha a textúrák rajzolása nehezebb, mint a sokszögek rajzolása. Ha olyan messzire kell kicsinyítenie, akkor jobb, ha nagyobb textúrákkal rendelkezik. Ugyanez vonatkozik a nagyításra is, nem szabad megrajzolni azokat a textúrákat, amelyeket nem kell rajzolni.

    Amit általában csinálok (nem vagyok Unity srác), létrehozok egy osztályt egy térképhez, és használok 2 dimenziós tömb az összes burkolatának megtartására. Ez a tömb lehet egyszerűen ints vagy egy csempe osztály, néhány inttal, amely utal a textúrájára, a cserép típusára, az objektumokra stb. Ezután az alábbiak szerint rajzolhatnánk:

    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); } } 

    Úgy tűnik, hogy az általam használt rajzolási módszer egy GUI megrajzolására szolgál, de tökéletesen alkalmas lehet a feladatra. Ellenkező esetben be kell ásni a sprite kezelőbe és megtalálni a módját ami ezzel a módszerrel működik.

    Használhat egy szótárat a textúra hivatkozásához, például int 1 a cseréposztályában valamilyen textúrára hivatkozik, és int 2 másra utal.Abban a sorban, amelyen a textúráját rajzolja, a szótár segítségével adja meg a megfelelő textúra objektumot. Így nem hozhat létre GameObject-et, és így nem hozhat létre minden felesleges költséget.

    Ugyanezt megteheti nagyjából mindenre, amire nincs szüksége a GameObject vezérlésének szintjére. Ne feledje azonban, hogy így megrajzolja a térkép minden lapkáját, és valószínűleg nem önti el automatikusan az objektumokat, mint azt hiszem, az egység a játékobjektumokkal. De egyszerűen megrajzolni, hogy mit kell a képernyőn megjeleníteni, nagyon egyszerű. Tudja a képernyő / nézetablak méretét, a kamera helyzetét és a csempeméretet. Néhány egyszerű matematikának pontosan meg kell rajzolnia, amire szükség van.

    Ennek ellenére az egység egy 3D-s motor. Csak 3D-ben támogatja a 2D-t. De alapvetően ugyanezt teheti a textúrákkal és a négyzetekkel is. egy ortográfiai kamera. Csak megrajzolni a szükséges hálókat elég olcsó.

    Válasz

    Voxel / blokk alapú projekten dolgozóként , Nem tehetek róla, hogy csak ugyanarra a megközelítésre gondolok, csak 2D-ben. Felépíthetsz egy rácsszerű hálót eljárási szempontból, és a textúra-atlaszban a csempe látványának megfelelő koordinátáit rendelheted az UV-csatornához. 3D-ben sokkal több munkát kell elvégezned mint ez a nagy teljesítmény érdekében, de a 2D-ben nagyon valószínű, hogy ez tényleg elég.

    Válasz

    Mindig használhatja a LeanPool-ot . Ingyenes eszköz az eszközboltban. Tárgy-gyűjtést végez az Ön számára. Ezután elvégezhet egy egyszerű selejtező rendszert a kameranézet körül, amely a csempés játékobjektumokat hozza létre / terjeszti, amikor belépnek vagy kilépnek a kamerák nézetéből. Nem vagyok biztos abban, hogy mekkora lesz a térképe, de a Unity elég sok játékobjektumot képes kezelni. A LeanPool-nak vannak benchmark-jelenetei a Unity-ben, ahol ezer objektumot tudsz ívni / de előidézni dobozos ütközéskomponensekkel, és úgy gondolom, hogy valószínűleg mindegyiken megjelenít egy komponenst is, és ezt nagyon gyorsan megcsinálja.

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

    Itt egy link jelenik meg példa a LeanPool használatára egy csempetérképpel.

    Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük