当前位置:   article > 正文

Unity 代码动态生成模型_addmeshdata 生成模型并添加材质球

addmeshdata 生成模型并添加材质球

网格由 3D 空间中排列的三角形组成,旨在产生实体对象的效果。三角形由其拐点或者顶点定义。在 Mesh 类中,顶点全部存储在单个数组中,并且每个三角形使用与顶点数组的索引对应的三个整数指定。这些三角形还将全部集合在一个整数数组中;从该数组的开头以三个为一组的方式解读数组中的整数,因此元素 0、1 和 2 定义第一个三角形,3、4 和 5 定义第二个三角形,依此类推。

Mesh类是对象网格几何体的基本脚本接口。该类使用数组来表示三角形、顶点位置、法线和纹理坐标,还提供了许多其他有用的属性和函数来辅助网格的生成。

Mesh 对象具有顶点及其关联数据(法线和 UV 坐标)的属性以及三角形数据的属性。顶点可按任何顺序提供,但是法线和 UV 的数组必须经过排序,使索引全部对应于顶点(即,法线数组的元素 0 提供顶点 0 的法线,依此类推)。顶点为 Vector3,表示对象局部空间中的点。法线为经过标准化的 Vector3,表示方向,同样位于局部坐标中。UV 指定为 Vector3,但由于 Vector2 类型没有名为 U 和 V 的字段,因此必须在脑海中将它们分别转换为 X 和 Y。

三角形指定为整数三元组,作为顶点数组的索引。该数组只是一个简单的整数索引列表,并不会使用特殊的类来表示三角形。它们针对每个三角形以三个为一组,因此前三个元素定义第一个三角形,接下来的三个定义第二个三角形,依此类推。三角形的一个重要细节是角顶点的排序问题。它们的排列应符合以下要求:当向下观看三角形的可见外表面时,角应顺时针转动,但从哪个角开始并不重要。

创建四边形

顶点数组

首先需要设置形状使用的顶点数组。

以下示例假定四边形位于 x 轴和 y 轴上,并且脚本中包含变量 width 和 height。

此示例按以下顺序提供顶点: 左下角、 右下角、 左上角、 右上角

  1. Vector3[] vertices = new Vector3[4]
  2. {
  3. new Vector3(0, 0, 0),
  4. new Vector3(width, 0, 0),
  5. new Vector3(0, height, 0),
  6. new Vector3(width, height, 0)
  7. };
  8. mesh.vertices = vertices;

三角形

接下来需要设置三角形。一个四边形由两个三角形组成,每个三角形由先前创建的顶点数组中的三个点组成。要指定这些点,请将每个三角形定义为顶点数组的三个索引。例如,此四边形的左下方三角形使用索引 0、2 和 1,对应于顶点数组中的坐标 (0, 0, 0)、(0, height, 0) 和 (width, 0, 0)。顺序很重要,因为必须按顺时针对角进行排序。右上方的三角形使用索引 2、3 和 1。

  1. int[] tris = new int[6]
  2. {
  3. // 左下方三角形
  4. 0, 2, 1,
  5. // 右上方三角形
  6. 2, 3, 1
  7. };
  8. mesh.triangles = tris;

法线

在场景中可以看到带有顶点和三角形的网格,但是 Unity 尚未对网格正确着色,因为这个网格还没有法线。此示例的法线很简单,因为这些法线都是相同的。每条法线均指向四边形本地空间中的负 z 轴方向。添加法线时,Unity 会正确对四边形着色,但是您需要在场景中有光源才能看到效果。

如果不想自己定义法线,则可以使用   mesh.RecalculateNormals();

  1. Vector3[] normals = new Vector3[4]
  2. {
  3. -Vector3.forward,
  4. -Vector3.forward,
  5. -Vector3.forward,
  6. -Vector3.forward
  7. };
  8. mesh.normals = normals;

纹理坐标

最后,要正确显示网格的材质上的纹理,请向网格添加纹理坐标。纹理坐标在 0 到 1 之间。网格中的每个顶点都有一个纹理坐标,用于指定材质的纹理上要采样的位置。要显示四边形上的整个纹理,每个顶点上的纹理坐标值都应全部为 0 或 1,以便四边形的每个角都对应于纹理的角。

  1. Vector2[] uv = new Vector2[4]
  2. {
  3. new Vector2(0, 0),
  4. new Vector2(1, 0),
  5. new Vector2(0, 1),
  6. new Vector2(1, 1)
  7. };
  8. mesh.uv = uv;

最终的脚本

  1. using UnityEngine;
  2. public class QuadCreator : MonoBehaviour
  3. {
  4. public float width = 1;
  5. public float height = 1;
  6. public void Start()
  7. {
  8. MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
  9. meshRenderer.sharedMaterial = new Material(Shader.Find("Standard"));
  10. MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
  11. Mesh mesh = new Mesh();
  12. Vector3[] vertices = new Vector3[4]
  13. {
  14. new Vector3(0, 0, 0),
  15. new Vector3(width, 0, 0),
  16. new Vector3(0, height, 0),
  17. new Vector3(width, height, 0)
  18. };
  19. mesh.vertices = vertices;
  20. int[] tris = new int[6]
  21. {
  22. // 左下方三角形
  23. 0, 2, 1,
  24. // 右上方三角形
  25. 2, 3, 1
  26. };
  27. mesh.triangles = tris;
  28. Vector3[] normals = new Vector3[4]
  29. {
  30. -Vector3.forward,
  31. -Vector3.forward,
  32. -Vector3.forward,
  33. -Vector3.forward
  34. };
  35. mesh.normals = normals;
  36. Vector2[] uv = new Vector2[4]
  37. {
  38. new Vector2(0, 0),
  39. new Vector2(1, 0),
  40. new Vector2(0, 1),
  41. new Vector2(1, 1)
  42. };
  43. mesh.uv = uv;
  44. meshFilter.mesh = mesh;
  45. }
  46. }

立方块

Mesh

立方块和面是同理的。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Test2 : MonoBehaviour
  5. {
  6. MeshFilter meshFilter;
  7. //存放定点的数据
  8. List<Vector3> verts;
  9. //定点的序号
  10. List<int> indices;
  11. void Start()
  12. {
  13. verts = new List<Vector3>();
  14. indices = new List<int>();
  15. meshFilter = GetComponent<MeshFilter>();
  16. Generate();
  17. }
  18. void Generate()
  19. {
  20. ClearMeshData();
  21. AddMeshData();
  22. Mesh mesh=new Mesh();
  23. mesh.vertices = verts.ToArray();
  24. mesh.triangles = indices.ToArray();
  25. //计算法线
  26. mesh.RecalculateNormals();
  27. //计算物体的边界
  28. mesh.RecalculateBounds();
  29. meshFilter.mesh = mesh;
  30. }
  31. void ClearMeshData()
  32. {
  33. verts.Clear();
  34. indices.Clear();
  35. }
  36. void AddMeshData()
  37. {
  38. verts.Add(new Vector3(0, 0, 0));
  39. verts.Add(new Vector3(0, 1, 0));
  40. verts.Add(new Vector3(1, 1, 0));
  41. verts.Add(new Vector3(1, 0, 0));
  42. verts.Add(new Vector3(1, 0, 0));
  43. verts.Add(new Vector3(1, 1, 0));
  44. verts.Add(new Vector3(1, 1, 1));
  45. verts.Add(new Vector3(1, 0, 1));
  46. verts.Add(new Vector3(0, 1, 0));
  47. verts.Add(new Vector3(0, 1, 1));
  48. verts.Add(new Vector3(1, 1, 1));
  49. verts.Add(new Vector3(1, 1, 0));
  50. verts.Add(new Vector3(0, 0, 0));
  51. verts.Add(new Vector3(1, 0, 0));
  52. verts.Add(new Vector3(1, 0, 1));
  53. verts.Add(new Vector3(0, 0, 1));
  54. verts.Add(new Vector3(0, 0, 1));
  55. verts.Add(new Vector3(1, 0, 1));
  56. verts.Add(new Vector3(1, 1, 1));
  57. verts.Add(new Vector3(0, 1, 1));
  58. verts.Add(new Vector3(0, 0, 0));
  59. verts.Add(new Vector3(0, 0, 1));
  60. verts.Add(new Vector3(0, 1, 1));
  61. verts.Add(new Vector3(0, 1, 0));
  62. for (int i = 0; i <= 20; i+=4)
  63. {
  64. indices.Add(0 + i);
  65. indices.Add(1 + i);
  66. indices.Add(2 + i);
  67. indices.Add(0 + i);
  68. indices.Add(2 + i);
  69. indices.Add(3 + i);
  70. }
  71. }
  72. }

CreatePrimitive

实际上在unity中是可以动态生成,unity中基础的模型的

   GameObject obj1 = GameObject.CreatePrimitive(PrimitiveType.Cube);

这样就可以生成一个方块。还可以生成一下几种形状,只要改变枚举就可以。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/115305
推荐阅读
相关标签
  

闽ICP备14008679号