2015-08-13 9 views
9

Używam tego zestawu samouczków: https://www.youtube.com/watch?v=owBt9SNKXCI&index=6&list=PLbghT7MmckI4qGA0Wm_TZS8LVrqS47I9R, aby dynamicznie budować układ mapy płytek. Działa do pewnego punktu, ale generuje bardzo dziwny układ z płytkami o rozmiarze 128 x 128 pikseli.W Unity3D śledzę samouczek tilemap. Jednak układ UV wychodzi dziwnie. Jak mogę to naprawić?

enter image description here

wyraźnie, że dziwny podział nie powinno się dziać, ale nie wydaje się wyśledzić, co się dzieje, aby ją wywołać. Oto moja wersja kodu, który jest przeważnie identyczny do wersji sans quill18creates jest kilka małych różnic:

using UnityEngine; 
using System.Collections; 

[ExecuteInEditMode] 
public class TileMap : MonoBehaviour { 

    public int size_x = 100; 
    public int size_z = 50; 
    public float tileSize = 1.0f; 

    public Texture2D terrainTiles; 
    int tileResolution = 128; 

    // Use this for initialization 
    void Start() { 
     BuildMesh(); 
    } 

    Color[][] ChopUpTiles() { 
     int numTilesPerRow = terrainTiles.width/tileResolution; 
     int numRows = terrainTiles.height/tileResolution; 

     Color[][] tiles = new Color[numTilesPerRow*numRows][]; 

     for(int y=0; y < numRows; y++) { 
      for(int x=0; x < numTilesPerRow; x++) { 
       tiles[y * numTilesPerRow + x] = terrainTiles.GetPixels(x*tileResolution , y*tileResolution, tileResolution, tileResolution); 
      } 
     } 

     return tiles; 
    } 

    void BuildTexture() { 
     //DTileMap map = new DTileMap(size_x, size_z); 

     int texWidth = size_x * tileResolution; 
     int texHeight = size_z * tileResolution; 
     Texture2D texture = new Texture2D(texWidth, texHeight); 

     Color[][] tiles = ChopUpTiles(); 


     for(int y=0; y < size_z; y++) { 
      for(int x=0; x < size_x; x++) { 
       Color[] p = tiles[Mathf.RoundToInt(Random.Range(0, 5))]; 
       texture.SetPixels(x * tileResolution, y * tileResolution, tileResolution, tileResolution, p); 
      } 
     } 

     //texture.filterMode = FilterMode.Bilinear; 
     texture.wrapMode = TextureWrapMode.Clamp; 
     texture.Apply(); 

     MeshRenderer mesh_renderer = GetComponent<MeshRenderer>(); 
     mesh_renderer.sharedMaterials[0].mainTexture = texture; 
    } 

    public void BuildMesh() { 
     int numTiles = size_x * size_z; 
     int numTris = numTiles * 2; 

     int vsize_x = size_x + 1; 
     int vsize_z = size_z + 1; 
     int numVerts = vsize_x * vsize_z; 

     // Generate the mesh data 
     Vector3[] vertices = new Vector3[ numVerts ]; 
     Vector3[] normals = new Vector3[numVerts]; 
     Vector2[] uv = new Vector2[numVerts]; 

     int[] triangles = new int[ numTris * 3 ]; 

     int x, z; 
     for(z=0; z < vsize_z; z++) { 
      for(x=0; x < vsize_x; x++) { 
       vertices[ z * vsize_x + x ] = new Vector3(x*tileSize, 0, -z*tileSize); 
       normals[ z * vsize_x + x ] = Vector3.up; 
       uv[ (z * vsize_x) + x ] = new Vector2((float)x/size_x, (float)z/size_z); 
      } 
     } 
     Debug.Log ("Done Verts!"); 

     for(z=0; z < size_z; z++) { 
      for(x=0; x < size_x; x++) { 
       int squareIndex = z * size_x + x; 
       int triOffset = squareIndex * 6; 
       triangles[triOffset + 0] = z * vsize_x + x +   0; 
       triangles[triOffset + 2] = z * vsize_x + x + vsize_x + 0; 
       triangles[triOffset + 1] = z * vsize_x + x + vsize_x + 1; 

       triangles[triOffset + 3] = z * vsize_x + x +   0; 
       triangles[triOffset + 5] = z * vsize_x + x + vsize_x + 1; 
       triangles[triOffset + 4] = z * vsize_x + x +   1; 
      } 
     } 

     // Create a new Mesh and populate with the data 
     Mesh mesh = new Mesh(); 
     mesh.vertices = vertices; 
     mesh.triangles = triangles; 
     mesh.normals = normals; 
     mesh.uv = uv; 

     // Assign our mesh to our filter/renderer/collider 
     MeshFilter mesh_filter = GetComponent<MeshFilter>(); 
     MeshCollider mesh_collider = GetComponent<MeshCollider>(); 

     mesh_filter.mesh = mesh; 
     mesh_collider.sharedMesh = mesh; 


     BuildTexture(); 
    } 
} 
+0

Czy ktoś chce coś zrobić? Podoba mi się ten pomysł na kod, po prostu nie mogę sprawić, że układ pozycjonowania UV działa tak, jak powinien działać. – Merlin

+0

Czy możesz podać, jakie są różnice? Wygląda na to, że właśnie tam chciałbyś wyglądać. – 31eee384

Odpowiedz

2

Nie rozumiem dokładnie, jaka część jest źle w obrazie, ale myślę, że to, że te same płytki zbijają się razem. Próbowałem Twojego kodu i działa dobrze dla mnie. Ale myślę, że następna część może być przyczyną lumping razem problem dla Ciebie:

Color[] p = tiles[Mathf.RoundToInt(Random.Range(0, 5))]; 

Zamiast tego należy zrobić:

Color[] p = tiles[Random.Range(0, 5)]; 

Bo w inny sposób, losowego generowania liczb zmiennoprzecinkowych, a może są one blisko siebie, że zaokrąglenie ich do liczby całkowitej daje tę samą płytkę. Spróbuj. Pamiętaj również, upewnij się, że szerokość i wysokość tekstury jest podzielna przez 128.

+0

Głównie poza obawiam się, chociaż uważam, że może to być funkcja ChopUpTiles powodująca to. Po prostu nie jestem pewien jak. – Merlin

+0

Myślę, że powieliłem problem. Maksymalny rozmiar tekstury w Unity wynosi 2^14 o 2^14. Gdy próbujesz utworzyć większą teksturę, daje to wyjątek podczas tworzenia tekstury, ale siatka jest tworzona tak czy inaczej. Tak więc tekstura rozciąga się wzdłuż siatki i wygląda na to, że płytki są ze sobą połączone. Jednym z wymiarów rozmiaru tekstury jest "size_x * tileResolution". Więc kiedy spróbujesz stworzyć większą siatkę, dostaniesz ten błąd. –

+0

W każdym razie zauważyłem, że jest to zły sposób na stworzenie tego rodzaju siatki. Możesz stworzyć więcej niż jedną siatkę, aby mieć większy świat, ale nadal uważam, że nie jest to dobry sposób. Zamiast tego powinieneś zrobić to tak: Użyj 4 wierzchołków dla każdego kafelka. Przypisz współrzędne uv zgodnie z ich położeniem na oryginalnej teksturze. I użyj oryginalnej tekstury w materiale. Więc nie twórz nowej tekstury. W ten sposób możesz mieć siatki o dowolnym rozmiarze, o ile ma on mniej niż 64k wierzchołków. Z drugiej strony nie ma sposobu na pokonanie wierzchołków 64k, więc musisz stworzyć kolejną siatkę, jeśli chcesz ją powiększyć. –

0

To był zdecydowanie problem z wielkością, ale wystąpił problem z pozycjonowaniem. Płytki muszą zaczynać się w lewym dolnym rogu układu współrzędnych, aby je znaleźć.

Powiązane problemy