如何更好地针对生成的六边形编写此过程UV映射?

时间:2019-01-18 15:01:39

标签: c# textures texture-mapping vertex

我正在尝试为动态生成的网格配置过程UV映射,但是目前运气不佳。我有一个1024x1024的纹理,其中瓦片的大小为256x,每个纹理4列和4行。我目前正在使用六边形,并且遇到了一些绊脚石。

运行系统时,它将生成以下内容:

enter image description here

有问题的纹理图集文件是这样的,其坐标系基于位于左下角的0到1和0,0:

enter image description here

应为实心绿色六角形。一切都安排在循环中,并且应该与顶点匹配,但这种方式无法正常工作,我无法弄清楚到底发生了什么。是否有更好的方法或更有效的方法来正确布置uv和缩放以匹配纹理中的六边形?我到目前为止的代码如下。它主要使用列表而不是数组来容纳其他结构。

using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class HexMesh: MonoBehaviour {

    Mesh hexMesh;
    MeshCollider meshCollider;
    public List<Vector3> vertices;
    public List<Vector2> uvs;
    List<int> triangles;

    int uvRows = 4;
    int uvCols = 4;
    float uvRadius;

    public Vector2 uvDefault;

    void Awake()
    {
        uvRadius = 1.0f / uvCols / 2.0f;
        uvDefault = new Vector2(uvRadius, uvRadius);
        GetComponent<MeshFilter>().mesh = hexMesh = new Mesh();
        meshCollider = gameObject.AddComponent<MeshCollider>();
        hexMesh.name = "Hex Mesh";
        vertices = new List<Vector3>();
        uvs = new List<Vector2>();
        triangles = new List<int>();
    }

    public void Triangulate(HexCell[] cells)
    {
        hexMesh.Clear();
        vertices.Clear();
        triangles.Clear();
        uvs.Clear();
        for (int i = 0; i < cells.Length; i++)
        {
            Triangulate(cells[i]);
        }

        hexMesh.vertices = vertices.ToArray();
        hexMesh.triangles = triangles.ToArray();

        hexMesh.uv = uvs.ToArray();
        meshCollider.sharedMesh = hexMesh;
        hexMesh.RecalculateNormals();
    }

    void Triangulate(HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;
        addHex(center);
    }

    void addHex(Vector3 hexCenter)
    {
        int vertexIndex = vertices.Count;

        Vector2[] uvVerts = new Vector2[6];


        Vector3 v = Vector3.forward;
        for (var k = 0; k < HexMetrics.corners.Length; k++)
        {
            vertices.Add(v * HexMetrics.outerRadius);
            Vector3 uv = v * HexMetrics.outerRadius;
            uvVerts[k] = new Vector2(uv.x, uv.z);
            v = Quaternion.AngleAxis(60.0f, Vector3.up) * v;
        }

        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 5);

        triangles.Add(vertexIndex + 5);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 4);

        triangles.Add(vertexIndex + 4);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 2);

        triangles.Add(vertexIndex + 2);
        triangles.Add(vertexIndex + 3);
        triangles.Add(vertexIndex + 4);

        for (int j = 0; j < 6; j++)
        {
            uvs.Add(uvVerts[j] + uvDefault);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在第二眼的帮助下,我们找出了问题所在-至少有两个部分。第一个是在代码中:

Vector3 uv = v * HexMetrics.outerRadius;
uvVerts[k] = new Vector2(uv.x, uv.z);

应该是

uvVerts[k] = new Vector2(v.x, v.z) * uvRadius;

第二个问题是,将着色器的平铺设置为完全关闭,当应该为1,1时应设置为0,0。