【问题标题】:UNITY: Meshes created through code not aligning with verticesUNITY:通过代码创建的网格不与顶点对齐
【发布时间】:2020-05-27 10:46:22
【问题描述】:

我在 Unity 中遇到了这个问题。在代码中,我为每个 Hex 声明了 13 个顶点。它们在下图中显示为小玩意(小灰点)。一些顶点相互重叠,因为每个 Hex 都应该生成自己的 Mesh。我这样做是为了轻松包装世界。

The issue

如您所见,最左下角的第一个网格是在正确的位置生成的,但从那时起,每个网格都向上或向左倾斜两倍。选择任何六边形后,正确的网格会突出显示(例如,单击左上角的六角会突出显示左上角的网格。顶点位于正确的位置,在我看来三角形也正确放置,让我想知道这有什么问题。下面是生成网格的代码:

以下代码在处理世界生成的 HexMap 游戏对象中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HexMap : MonoBehaviour
{
    //The reference to the prefab
    public GameObject hexPrefab;

    public int numRows = 10;
    public int numColumns = 10;

    private GameObject[,] hexes;

    void Start()
    {
        GenerateMap();
    }

    public void GenerateMap()
    {
        //Initiate array to store all hexes
        hexes = new GameObject[numRows, numColumns];

        //Loop through all rows for each column to generate hexes
        for (int c = 0; c < numColumns; c++)
        {
            for (int r = 0; r < numRows; r++)
            {
                //Instantiate hex and assign it to the hexes-array
                GameObject hexObject = (GameObject)Instantiate(hexPrefab);
                hexes[c, r] = hexObject;

                //Access the Hex.cs script within the Hex gameobject
                Hex hex = hexObject.GetComponent<Hex>();

                //Make the Hex a child of the HexMap gameobject (mainly for clarity in the Unity hierarchy)
                hexObject.transform.parent = this.transform;

                //Set the column and row values in the Hex.cs to the current column and row
                hex.SetValues(c, r);
                //Call the position-method in Hex.cs to calculate the position of the Hex (it's default position would be 0,0,0 but it's changed here)
                hexObject.transform.position = hex.Position();
                //Call the method in Hex.cs to create its mesh, vertices and triangles
                hex.CreateMesh();

                //Change the label on a hex to read its column and row (only for debugging)
                hexObject.GetComponentInChildren<TextMesh>().text = string.Format("{0},{1}",c,r);
            }
        }
    }
}

并且Hex.cs脚本中存在如下代码,它是我们实例化的每个Hex的一个组件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hex : MonoBehaviour
{
    public int column;
    public int row;
    public readonly int negativeDistance; //the negative distance is the negative of (column + row) (this will be used to calculate the distance between two hexes

    public Mesh mesh;

    public Vector3[] vertices = new Vector3[13];
    public int[] triangles = new int[36];

    public float radius = 1f;
    static readonly float WIDTH_MULTIPLIER = Mathf.Sqrt(3) / 2;

    void Start()
    {

    }

    void Update()
    {
        UpdateMesh();
    }

    public void SetValues(int column, int row)
    {
        this.column = column;
        this.row = row;
        name = string.Format("Hex: {0},{1}", column, row);
    }

    //Returns the world-space position of this hex
    public Vector3 Position()
    {
        return new Vector3(HexHorizontalSpacing() * (column + row / 2f), 0, HexVerticalSpacing() * row);
    }

    //Returns the height of a single hex (from side to side)
    public float HexHeight()
    {
        return radius * 2;
    }

    //Returns the width of a hex (from point to point)
    public float HexWidth()
    {
        return WIDTH_MULTIPLIER * HexHeight();
    }

    //Returns the space between two hexes verticallrow
    public float HexVerticalSpacing()
    {
        return HexHeight() * 0.75f;
    }

    //Returns the space between two hexes horizontallrow
    public float HexHorizontalSpacing()
    {
        return HexWidth();
    }

    public void CreateMesh()
    {
        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;

        vertices[0] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2, 0, row * 1.5f);
        vertices[1] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 + Mathf.Sqrt(3) / 4, 0, row * 1.5f + 0.75f);  //1
        vertices[2] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 + Mathf.Sqrt(3) / 2, 0, row * 1.5f + 0.5f);  //2
        vertices[3] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 + Mathf.Sqrt(3) / 2, 0, row * 1.5f + 0);  //3
        vertices[4] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 + Mathf.Sqrt(3) / 2, 0, row * 1.5f - 0.5f);  //4
        vertices[5] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 + Mathf.Sqrt(3) / 4, 0, row * 1.5f - 0.75f);  //5
        vertices[6] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2, 0, -1f + row * 1.5f);  //6
        vertices[7] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 - Mathf.Sqrt(3) / 4, 0, row * 1.5f - 0.75f);  //7      
        vertices[8] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 - Mathf.Sqrt(3) / 2, 0, row * 1.5f - 0.5f);  //8       
        vertices[9] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 - Mathf.Sqrt(3) / 2, 0, row * 1.5f + 0);  //9
        vertices[10] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 - Mathf.Sqrt(3) / 2, 0, row * 1.5f + 0.5f);  //10
        vertices[11] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2 - Mathf.Sqrt(3) / 4, 0, row * 1.5f + 0.75f);  //11
        vertices[12] = new Vector3(column * Mathf.Sqrt(3) + row * Mathf.Sqrt(3) / 2, 0, 1f + row * 1.5f);  //12

        triangles[0] = 0;
        triangles[1] = 12;
        triangles[2] = 1;


        for (int i = 1; i <= 11; i++)
        {
            triangles[i * 3] = 0;
            triangles[i * 3 + 1] = i;
            triangles[i * 3 + 2] = i + 1;
        }

        UpdateMesh();
    }

    public void UpdateMesh()
    {
        mesh.Clear();

        mesh.vertices = vertices;

        mesh.triangles = triangles;

        mesh.RecalculateNormals();
    }

    public void OnDrawGizmos()
    {
        if (vertices == null) return;

        for (int i = 0; i < vertices.Length; i++)
        {
            Gizmos.DrawSphere(vertices[i], .1f);
        }
    }
}

【问题讨论】:

  • 我不确定我是否得到它,结果正方形的形式应该是矩形还是当前的一般形式(钝角正方形)?如果是第一个,它们在右边,而不是左边,这让我有点困惑^^'

标签: c# unity3d mesh vertices


【解决方案1】:

好的,可能为时已晚 - 但由于问题仍然开放和查看,这里是一个简短的答案:

当您在 CreateMesh() 中创建网格时,您使用当前列和行值来定位顶点。如果在同一个网格中创建所有 Hex 单元,这将是可以的,但是由于您为每个 Hex 单元创建一个网格,然后定位 Hex 单元,您不应该在局部网格计算中使用列和行变量。

    vertices[0] = new Vector3(0, 0, 0);
    vertices[1] = new Vector3(Mathf.Sqrt(3) / 4, 0, 0.75f);  //1
    vertices[2] = new Vector3(Mathf.Sqrt(3) / 2, 0, 0.5f);  //2
    vertices[3] = new Vector3(Mathf.Sqrt(3) / 2, 0, 0);  //3
    vertices[4] = new Vector3(Mathf.Sqrt(3) / 2, 0, -0.5f);  //4
    vertices[5] = new Vector3(Mathf.Sqrt(3) / 4, 0, -0.75f);  //5
    vertices[6] = new Vector3(0, 0, -1f);  //6
    vertices[7] = new Vector3(-Mathf.Sqrt(3) / 4, 0, -0.75f);  //7      
    vertices[8] = new Vector3(-Mathf.Sqrt(3) / 2, 0, -0.5f);  //8       
    vertices[9] = new Vector3(-Mathf.Sqrt(3) / 2, 0, 0);  //9
    vertices[10] = new Vector3(-Mathf.Sqrt(3) / 2, 0, 0.5f);  //10
    vertices[11] = new Vector3(-Mathf.Sqrt(3) / 4, 0, 0.75f);  //11
    vertices[12] = new Vector3(0, 0, 1f);  //12

而且由于所有 Hex-cells 现在都有相同的顶点,您可以制作一个简单的网格并与所有 Hex-cells 共享,无需计算多个具有相同值的网格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-13
    • 2017-03-17
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    相关资源
    最近更新 更多