Generación de TileMap de procedimiento de Unity sin crear gameobject por mosaico

He estado buscando en Internet para encontrar una manera eficiente de crear un mapa de mosaico de procedimiento sin crear un GameObject por mosaico. Todos los tutoriales de TileMap que he encontrado están creando mosaicos creando cientos de GameObjects. Por lo tanto, la jerarquía en Unity se está expandiendo inesperadamente.

Estoy bastante seguro de que esta no es la forma «correcta» de hacerlo. Especialmente después de ver las nuevas herramientas Unity 2D que soportan mosaicos. Unity lo hizo así, puedes crear mosaicos en «un» objeto de juego, no para cada mosaico.

Entonces, ¿cómo lo hago de la manera correcta y eficiente?

Comentarios

  • Usted ‘ ha publicado esto en dos sitios SE. Elija uno.
  • Qué ‘ ¿Es tu preocupación específica la creación de un gran número de GameObjects? Si ‘ es solo un desorden jerárquico, hay formas fáciles de solucionarlo. Unity ‘ s el procesamiento por lotes debería combinar mosaicos similares en un solo lote de todos modos, por lo que ‘ es poco probable que sea una penalización importante en la llamada de sorteo al hacerlo de esta manera. el tiempo dedicado a las funciones de actualización de mosaicos también son problemas que se pueden resolver. ¿Ha perfilado su juego e identificado un c cuello de botella que ‘ estás tratando de resolver?
  • @DMGregory Bueno, si pensamos en un mapa 100 * 100 en la pantalla (si asumimos que nos alejamos para ver map), hará 10.000 gameobjects en la escena. También significa 10.000 componentes transformados unncesarios. No ‘ ni siquiera sé si la unidad puede soportar 10.000 objetos en la ventana de jerarquía. Sé que se congela después de un par de cientos.

Respuesta

Esto es lo que estoy consciente:

Opción 1. GameObject por mosaico. No es completamente horrible en ciertos casos. Dependiendo de sus necesidades, podría funcionar … bastante bien.

Opción 2. Un solo quad o plano que hace referencia a una textura que crea en tiempo de ejecución. Básicamente, usa la textura de tu atlas de mosaicos para «pintar» tu mapa como una nueva textura. Dependiendo del tamaño de tu mapa, por supuesto, es posible que desees tener varios cuadrantes / planos, cada uno de los cuales representa partes de tu mapa.

Opción 3. Cree su propia malla. Este sería probablemente el método que más le gustará una vez implementado. Le dará mucha flexibilidad y probablemente el mayor rendimiento. Básicamente, crearía un cuadrante por mosaico y establecería cada vértice UV para mapear los mosaicos en su atlas de mosaicos.

Para la Opción 2, I » Sugiero ver esta serie de videos de quill18creates: Serie de tutoriales de 3D TileMap de quill18creates

Para la Opción 3, este es mi código, con ajustes, por lo que puede que no sea perfecto:

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

Comentarios

  • Tus respuestas me ayudaron en el dias. Ahora, estoy revisando mis preguntas anteriores y ‘ me he dado cuenta de que ‘ nunca verifiqué esta respuesta como aceptada. Perdón por una eternidad de aprobación ^^ Gracias por la respuesta.

Responder

Como usted (creo ) al que se alude, la hoja de ruta de Unity tiene planes para un editor de mapas de mosaicos. Estoy deseando que llegue, porque ahora mismo es un poco confuso cómo proceder.

Mientras tanto, el mejor enfoque es «Lo que veo es hacer su mapa en Tiled y luego usar X-UniTMX para importarlo a Unity. Obviamente, eso no es una generación procedimental; me imagino que usarías la misma técnica que X-UniTMX está usando para crear la malla.

Respuesta

Podrías crear los mosaicos más profundamente en la jerarquía y cerrar esa carpeta y no te molestes. Lo que también puedes hacer es ocultar tus objetos de juego de la jerarquía `myTile.hideFlags = HideFlags. HideInHierarchy «no estoy seguro de cuánto rendimiento se obtendría.

Mostrar texturas de 100×100 en la pantalla nunca es una buena idea dibujar texturas es más pesado que dibujar polígonos de todos modos. Si necesita alejarse tanto, estará mejor con texturas más grandes. Lo mismo ocurre con el zoom, no debes dibujar las texturas que no necesitan ser dibujadas.

Lo que suelo hacer (no soy un chico de Unity) es crear una clase para un mapa y usar una matriz bidimensional para contener todos sus mosaicos. Esta matriz podría ser simplemente de ints o una clase Tile con un par de ints que se refieren a sus texturas, tipo de mosaico, objetos, etc. Luego, se dibujaría de la siguiente manera:

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

El método de dibujo que utilizo parece ser para dibujar una GUI, pero podría ser perfectamente adecuado para la tarea. De lo contrario, tienes que profundizar en el administrador de sprites y encontrar una manera que funciona con este método.

Podrías usar un diccionario como referencia de textura como int 1 en tu clase de mosaico se refiere a alguna textura y int 2 se refiere a otro.En la línea en la que está dibujando su textura, usaría su diccionario para dar el objeto de textura correcto. De esta manera, no debería crear un GameObject y, por lo tanto, no crear todos los gastos generales innecesarios.

Puede hacer lo mismo para prácticamente todo lo que no necesita el nivel de control de un GameObject. Sin embargo, tenga en cuenta que de esta manera dibujará cada mosaico de su mapa, lo más probable es que no elimine automáticamente los objetos como creo que lo hace la unidad con los objetos del juego. Pero simplemente dibujar lo que necesita estar en la pantalla es muy fácil. Conoce el tamaño de la pantalla / ventana gráfica, la posición de la cámara y el tamaño del mosaico. Algunas matemáticas simples deberían dibujar exactamente lo que se necesita.

Aún así, unity es un motor 3D. Simplemente admite 2D en una forma 3D. Pero básicamente puedes hacer lo mismo para quads / mallas con texturas y una cámara ortográfica. Dibujar las mallas necesarias es bastante barato.

Responder

Como alguien que trabaja en un proyecto basado en bloques / voxel , No puedo evitar pensar en usar el mismo enfoque, solo en 2D. Puede construir una malla similar a una cuadrícula de forma procedimental y asignar las coordenadas correctas de las imágenes de mosaicos en su atlas de texturas al canal UV. En 3D tiene que hacer mucho más que esto para tener un alto rendimiento, pero en 2D es muy probable que sea realmente suficiente.

Respuesta

Siempre puede usar LeanPool . Es un activo gratuito en la tienda de activos. Realiza la agrupación de objetos para usted. Luego, puede hacer un sistema de selección simple alrededor de la vista de cámaras que genera / genera objetos de juego de mosaicos a medida que ingresan / salen de la vista de cámaras. No estoy seguro de qué tan grande será tu mapa de mosaicos, pero Unity puede manejar muchos objetos del juego. LeanPool tiene escenas de referencia en Unity donde puede generar / generar mil objetos con componentes de colisión de cajas y creo que posiblemente también un componente de renderizado en cada uno y lo hace muy, muy rápido.

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

Aquí hay un enlace que le mostrará un ejemplo del uso de LeanPool con un mapa de mosaicos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *