C# 在Unity3D中,我将学习tilemap教程。然而,UV布局变得很奇怪。我怎样才能解决这个问题?

C# 在Unity3D中,我将学习tilemap教程。然而,UV布局变得很奇怪。我怎样才能解决这个问题?,c#,unity3d,uv-mapping,C#,Unity3d,Uv Mapping,我将遵循以下教程集:动态构建平铺贴图布局。它在某种程度上是可行的,但它生成了一个非常奇怪的布局,具有128 x 128大小的瓷砖 很明显,这种奇怪的分区不应该发生,但我似乎无法找到导致它的原因。这是我的代码版本,与quill18creates的版本基本相同,但有一些小的区别: using UnityEngine; using System.Collections; [ExecuteInEditMode] public class TileMap : MonoBehaviour {

我将遵循以下教程集:动态构建平铺贴图布局。它在某种程度上是可行的,但它生成了一个非常奇怪的布局,具有128 x 128大小的瓷砖

很明显,这种奇怪的分区不应该发生,但我似乎无法找到导致它的原因。这是我的代码版本,与quill18creates的版本基本相同,但有一些小的区别:

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();
    }   
}
使用UnityEngine;
使用系统集合;
[执行编辑模式]
公共类TileMap:单行为{
公共整数大小_x=100;
公共整数大小_z=50;
公共浮点数tileSize=1.0f;
公共纹理2D地衣;
int-tileResolution=128;
//用于初始化
无效开始(){
BuildMesh();
}
颜色[][]Choputles(){
int numTilesPerRow=terrainTiles.width/tileResolution;
int numRows=地形高度/tileResolution;
颜色[][]瓷砖=新颜色[numTilesPerRow*numRows][];
对于(int y=0;y
我不知道图像中到底是哪一部分出错,但我认为是同一块瓷砖在一起。 我试过你的代码,它对我很有效。但我猜以下部分可能会导致您出现“集中”问题:

Color[] p = tiles[Mathf.RoundToInt(Random.Range(0, 5))];
相反,你应该:

Color[] p = tiles[Random.Range(0, 5)];
因为,另一种方式,Random生成浮点数,可能它们彼此接近,将它们四舍五入到整数会得到相同的平铺。试试看。
另外提醒一下,确保纹理的宽度和高度可以被128整除。

好吧,这肯定是尺寸问题,但定位也有问题。瓷砖必须从左下角开始,坐标系才能找到它们。

有人愿意尝试一下吗?我喜欢这段代码的想法,只是我似乎无法让UV定位布局按它应该的方式工作。你能告诉我区别是什么吗?这似乎是你想看的地方。我恐怕大部分是错的,尽管我相信这可能是因为Chopperples函数造成的。我只是不知道怎么做。我想我重现了这个问题。Unity中的最大纹理大小为2^14 x 2^14。当您尝试生成更大的纹理时,创建纹理时会出现异常,但无论如何都会创建网格。所以纹理沿着网格延伸,看起来就像瓷砖在一起。纹理大小的一维由
size\u x*tileResolution
决定。所以当你尝试创建一个更大的网格时,你会得到这个错误。不管怎样,我注意到这是一个创建这种网格的坏方法。您可以创建多个网格以拥有更大的世界,但我仍然认为这不是一个好方法。相反,您应该这样做:为每个平铺使用4个顶点。根据uv坐标在屏幕上的位置指定uv坐标