After the procedural generation of the grid, a lift appears on the object, even though I correctly generated the sweep. If you find my mistake, please describe what it is. I'll be very grateful.

Mesh generation:

using UnityEngine; using System.Linq; using System.Collections; using System.Collections.Generic; namespace PlasticBlock.Melting { [RequireComponent(typeof(MeshRenderer)), RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(UVWEditor)), ExecuteInEditMode] public class BodyGenerator : MonoBehaviour { /// <summary> /// Количество граней у тела. /// </summary> public int edges; /// <summary> /// Количество генерируемых сегментов. /// </summary> public int heightSegments; /// <summary> /// Сегменты тела. Значения радиуса и высоты сегмента. /// </summary> public Vector2[] segments; /// <summary> /// Минимальные габариты сегмента. /// </summary> public Vector2 minRadius; /// <summary> /// Максимальные габариты сегмента. /// </summary> public Vector2 maxRadius; private UVWEditor _uvwEditor; private MeshRenderer _renderer; private MeshFilter _filter; private Mesh _mesh; private void Update() { Init(); } /// <summary> /// Начало генерации процедурно генерируемой сетки. /// </summary> public void Init() { _renderer = GetComponent<MeshRenderer>(); _filter = GetComponent<MeshFilter>(); _uvwEditor = GetComponent<UVWEditor>(); _mesh = new Mesh(); _mesh.name = "Procedural Generated Object"; _mesh.MarkDynamic(); GenerateBody(); _mesh = _uvwEditor.Calculate(_mesh, edges, heightSegments); _filter.mesh = _mesh; } /// <summary> /// Процедурная генерация сетки. /// </summary> private void GenerateBody() { int n = 0; _mesh.Clear(); Vector3[] vertices = new Vector3[edges * heightSegments]; int[] links = new int[edges * heightSegments * 6 - 6]; for (int m = 0, i = 0; i < heightSegments; i++) { for (float theta = 0; theta < 2 * Mathf.PI; theta += Mathf.PI * 2 / edges, m++) { segments[i].x = segments[i].x >= minRadius.x ? segments[i].x : minRadius.x; segments[i].x = segments[i].x <= maxRadius.x ? segments[i].x : maxRadius.x; float y = segments[i].y + i * minRadius.y; float x = segments[i].x * Mathf.Cos(theta); float z = segments[i].x * Mathf.Sin(theta); Vector3 pos = new Vector3(x, y, z); vertices[m] = pos; if (i == 1) n++; } } int k = 0; for (int i = 0; i < edges * (heightSegments - 1); i++) { int zeroPoint = i; int upperPoint = i + n; if ((i + 1) % edges == 0) { links[k] = zeroPoint; k++; links[k] = upperPoint; k++; links[k] = upperPoint - edges + 1; k++; links[k] = zeroPoint; k++; links[k] = upperPoint - edges + 1; k++; links[k] = zeroPoint - edges + 1; k++; } else { links[k] = zeroPoint; k++; links[k] = upperPoint; k++; links[k] = upperPoint + 1; k++; links[k] = zeroPoint; k++; links[k] = upperPoint + 1; k++; links[k] = zeroPoint + 1; k++; } } _mesh.vertices = vertices; _mesh.triangles = links; _mesh.Optimize(); _mesh.RecalculateNormals(); _mesh.RecalculateBounds(); } } } 

Scan generation:

 using UnityEngine; using System.Collections; namespace PlasticBlock.Melting { /// <summary> /// Генератор развёртки. /// </summary> [ExecuteInEditMode] public class UVWEditor : MonoBehaviour { /// <summary> /// Массив точек развёртки. /// </summary> public Vector2[] uvs; private int _edges, _heightSegments; private Mesh _mesh; private Texture2D _texture; /// <summary> /// Начало расчётов развёртки. /// </summary> /// <param name="mesh">Сетка.</param> /// <param name="edges">Количество краёв.</param> /// <param name="heightSegments">Количество сегментов.</param> /// <returns></returns> public Mesh Calculate(Mesh mesh, int edges, int heightSegments) { _mesh = mesh; _edges = edges; _heightSegments = heightSegments; CalculateUVWs(); return _mesh; } private void CalculateUVWs() { uvs = new Vector2[_edges * _heightSegments]; for (int y = 0; y < _heightSegments; y++) { for (int x = 0; x < _edges; x++) { float px = 1f / _edges * x; float py = 1f / (_heightSegments - 1) * y; uvs[y * _edges + x] = new Vector2(px,py); } } _mesh.uv = uvs; _mesh.uv2 = uvs; _mesh.uv3 = uvs; _mesh.uv4 = uvs; } } } 

Thanks for attention.

  • If you are given an exhaustive answer, mark it as correct (a daw opposite the selected answer). - Nicolas Chabanovsky

1 answer 1

Here is the working code made from yours.

 using UnityEngine; using System.Linq; using System.Collections; using System.Collections.Generic; namespace PlasticBlock.Melting { [RequireComponent(typeof(MeshRenderer)), RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(UVWEditor)), ExecuteInEditMode] public class BodyGenerator : MonoBehaviour { /// <summary> /// Количество граней у тела. /// </summary> public int edges; /// <summary> /// Количество генерируемых сегментов. /// </summary> public int heightSegments; /// <summary> /// Сегменты тела. Значения радиуса и высоты сегмента. /// </summary> public Vector2[] segments; /// <summary> /// Минимальные габариты сегмента. /// </summary> public Vector2 minRadius; /// <summary> /// Максимальные габариты сегмента. /// </summary> public Vector2 maxRadius; private UVWEditor _uvwEditor; private MeshRenderer _renderer; private MeshFilter _filter; private Mesh _mesh; private void Update() { Init(); } /// <summary> /// Начало генерации процедурно генерируемой сетки. /// </summary> public void Init() { _renderer = GetComponent<MeshRenderer>(); _filter = GetComponent<MeshFilter>(); _uvwEditor = GetComponent<UVWEditor>(); _mesh = new Mesh(); _mesh.name = "Procedural Generated Object"; _mesh.MarkDynamic(); GenerateBody(); _mesh = _uvwEditor.Calculate(_mesh, edges, heightSegments); _filter.mesh = _mesh; } /// <summary> /// Процедурная генерация сетки. /// </summary> private void GenerateBody() { int n = 0; _mesh.Clear(); Vector3[] vertices = new Vector3[(edges + 1) * heightSegments]; int[] links = new int[edges * heightSegments * 6 - 6]; for (int m = 0, i = 0; i < heightSegments; i++) { for (float theta = 0; theta < 2 * Mathf.PI + Mathf.PI * 2 / edges; theta += Mathf.PI * 2 / edges, m++) { segments[i].x = segments[i].x >= minRadius.x ? segments[i].x : minRadius.x; segments[i].x = segments[i].x <= maxRadius.x ? segments[i].x : maxRadius.x; float y = segments[i].y + i * minRadius.y; float x = segments[i].x * Mathf.Cos(theta); float z = segments[i].x * Mathf.Sin(theta); Vector3 pos = new Vector3(x, y, z); vertices[m] = pos; if (i == 1) n++; } } int k = 0; for (int i = 0; i < (edges + 1) * (heightSegments - 1); i++) { int zeroPoint = i; int upperPoint = i + edges + 1; if ((i + 1) % (edges + 1) == 0) continue; else { links[k] = zeroPoint; k++; links[k] = upperPoint; k++; links[k] = upperPoint + 1; k++; links[k] = zeroPoint; k++; links[k] = upperPoint + 1; k++; links[k] = zeroPoint + 1; k++; } } _mesh.vertices = vertices; _mesh.triangles = links; _mesh.Optimize(); _mesh.RecalculateNormals(); _mesh.RecalculateBounds(); } } } 

.

 using UnityEngine; using System.Collections; namespace PlasticBlock.Melting { /// <summary> /// Генератор развёртки. /// </summary> [ExecuteInEditMode] public class UVWEditor : MonoBehaviour { /// <summary> /// Массив точек развёртки. /// </summary> public Vector2[] uvs; private int _edges, _heightSegments; private Mesh _mesh; private Texture2D _texture; /// <summary> /// Начало расчётов развёртки. /// </summary> /// <param name="mesh">Сетка.</param> /// <param name="edges">Количество краёв.</param> /// <param name="heightSegments">Количество сегментов.</param> /// <returns></returns> public Mesh Calculate(Mesh mesh, int edges, int heightSegments) { _mesh = mesh; _edges = edges; _heightSegments = heightSegments; CalculateUVWs(); return _mesh; } private void CalculateUVWs() { uvs = new Vector2[(_edges + 1) * _heightSegments]; for (int y = 0; y < _heightSegments; y++) { for (int x = 0; x < _edges + 1; x++) { float px = 1f / _edges * x; float py = 1f / (_heightSegments - 1) * y; uvs[y * (_edges + 1) + x] = new Vector2(px, py); } } _mesh.uv = uvs; _mesh.uv2 = uvs; _mesh.uv3 = uvs; _mesh.uv4 = uvs; } } } 

But honestly, it was easier to write again. Instead of simple and clear cycles for integers i, j, then you have a cycle on float (dangerous), then continuous numbering, and then pick out j by division (unreadable).

The basic idea of ​​editing: I added another row of points that coincide with the zero row in the coordinates of the vertices, and they differ in UV coordinates, reaching U by one, thus 0 reached 1, forming a seam. http://take.ms/QwCSV