ЕДИНСТВО: Меши, созданные с помощью кода, не выравниваются по вершинам - PullRequest
0 голосов
/ 27 мая 2020

Я столкнулся с этой проблемой с Unity. В коде я объявил 13 вершин для каждого Hex. На следующем рисунке они видны как вещицы (маленькие серые точки). Некоторые вершины перекрывают друг друга, поскольку каждый Hex должен генерировать свой собственный Me sh. Я сделал это, чтобы можно было легко обернуть мир.

Проблема

Как видите, генерируется первый me sh в самом нижнем левом углу в правильном положении, но с этого момента каждый me sh будет вдвое больше вверх или влево. При выборе любого из шестигранников выделяется правильный me sh (например, нажатие на верхний левый Hex выделяет верхний левый Me sh. Вершины находятся в правильном положении, и мне кажется, что треугольники также размещены правильно, что заставляет меня задуматься, что с этим не так. Ниже приведен код, который генерирует сетки:

Следующий код находится в игровом объекте 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);
        }
    }
}
...