搜档网
当前位置:搜档网 › 【Unity】Mesh网格编程(一)正二十面体

【Unity】Mesh网格编程(一)正二十面体

【Unity】Mesh网格编程(一)正二十面体
【Unity】Mesh网格编程(一)正二十面体

【Unity】Mesh网格编程(一)正二十面体

本文以自定义编译器菜单的方式,实现了Unity创建正二十面体的功能扩展。本文分享自蓝鸥科技杜老师。

Mesh类是Unity用脚本创建和修改3D模型的重要脚本类。

添加了各种Shader材质球+Halo的效果图:

关于Mesh编程相关内容网上有很多资料,这里就不再赘述了。

步骤一:

创建Editor文件夹(若有就不用),将以下源代码保存为MyEditor.cs文件,存入文件夹中。

源代码:

1.///

2./// Mesh网格编程——点击拓展菜单,创建正二十面体

3./// Created by 杜子兮(https://www.sodocs.net/doc/6812528334.html,) 2015.2.20

4./// https://www.sodocs.net/doc/6812528334.html, All Rights Reserved.

5.///

6.

https://www.sodocs.net/doc/6812528334.html,ing UnityEngine;

https://www.sodocs.net/doc/6812528334.html,ing UnityEditor; // 使用编译器类

https://www.sodocs.net/doc/6812528334.html,ing System.Collections;

10.

11.public class MyEditor : EditorWindow {

12.

13.// 注意:该类继承EditorWindow,只能包含静态成员

14.

15.static Mesh mesh; // 网格

16.static Vector3[] Vs; // 模型顶点坐标数组

17.static Vector2[] UVs; // UV贴图坐标

18.static Vector3[] normals; // 法线

19.static Vector4[] tangents; // 切线

20.static int[] Ts; // 三角形的点序列

21.

22.// 添加菜单项,并放置最顶端

23. [MenuItem("GameObject/Create Other/正二十面体", false, -30)]

24.static void CreateRegular(){

25.// 先按12个顶点开辟顶点数组

26. Vs = new Vector3[12];

27.

28.// 正二十面体顶点公式(度娘可查)

29.float m = Mathf.Sqrt(50 - 10 * Mathf.Sqrt(5)) / 10;

30.float n = Mathf.Sqrt(50 + 10 * Mathf.Sqrt(5)) / 10;

31.

32.// 按公式顺序对顶点坐标赋值

33. Vs[0] = new Vector3( m, 0, n);

34. Vs[1] = new Vector3( m, 0,-n);

35. Vs[2] = new Vector3(-m, 0, n);

36. Vs[3] = new Vector3(-m, 0,-n);

37. Vs[4] = new Vector3( 0, n, m);

38. Vs[5] = new Vector3( 0,-n, m);

39. Vs[6] = new Vector3( 0, n,-m);

40. Vs[7] = new Vector3( 0,-n,-m);

41. Vs[8] = new Vector3( n, m, 0);

42. Vs[9] = new Vector3(-n, m, 0);

43. Vs[10] = new Vector3( n,-m, 0);

44. Vs[11] = new Vector3(-n,-m, 0);

45.

46.// 正二十面体三角形的点序列

47. Ts = new int[] {6,4,8, 9,4,6, 6,3,9, 6,1,3, 6,8,1,

48. 8,10,1, 8,0,10, 8,4,0, 4,2,0, 4,9,2,

49. 9,11,2, 9,3,11, 3,1,7, 1,10,7, 10,0,5,

50. 0,2,5, 2,11,5, 3,7,11, 5,11,7, 10,5,7};

51.

52.// 根据面的顺序,重新创建新的顶点数组,用于计算顶点法线

53. Vector3[] newVs = new Vector3[Ts.Length];

54.for (int i = 0; i < newVs.Length; i++) {

55. Debug.Log(Vs[Ts[i]]);

56. newVs[i] = Vs[Ts[i]];

57. }

58. Vs = newVs;

59. UVs = new Vector2[Vs.Length];

60. normals = new Vector3[Vs.Length];

61. tangents = new Vector4[Vs.Length];

62.

63.// 根据新的点,设置三角面的顶点ID并计算点法线

64.for (int i = 0; i < Ts.Length - 2; i+=3) {

65. Vector3 normal = Vector3.Cross(Vs[i + 1] - Vs[i], Vs[i + 2] - Vs

[i]); // 计算点的法线

66.for (int j = 0; j < 3; j++) {

67. Ts[i + j] = i + j; // 重新设置面的顶点ID

68. normals[i + j] = normal; // 点的法线赋值

69. }

70. }

71.

72.// 设置每个点的切线和UV

73.for (int i = 0; i < Vs.Length; i++) {

74. tangents[i] = new Vector4(-1, 0, 0, -1); // 切线

75. UVs[i] = new Vector2(Vs[i].x, Vs[i].y); // UV坐标

76. }

77.

78.// 调用创建对象函数

79. CreateObjectByMesh("Icosahedron");

80. }

81.

82.// 创建对象函数(这个功能提出来,方便以后扩展)

83.static void CreateObjectByMesh(string name) {

84. GameObject regular = new GameObject(); // 创建游戏对象

85. https://www.sodocs.net/doc/6812528334.html, = name; // 根据参数命名

86. regular.AddComponent(); // 添加MeshFilter组件

87. regular.AddComponent(); // 添加MeshRenderer组件

88.

89. mesh = new Mesh(); // 创建网格

90. mesh.vertices = Vs; // 网格的顶点

91. mesh.triangles = Ts; // 网格的三角形

92. mesh.uv = UVs; // 网格的UV坐标

93. mesh.normals = normals; // 网格的法线

94. mesh.tangents = tangents; // 网格的切线

95. regular.GetComponent().mesh = mesh; // 添加网格

96. }

97.

98.}

步骤二:

在菜单中选择

GameObject -> Create Other -> 正二十面体

创建正二十面体游戏对象。

步骤三:

可根据喜好添加材质,选择Shander以及其他效果。

后语

正二十面体的实现有一个比较特别的地方,就是顶点数组创建了两次。

因为空间上的规律比较难搞,所以第一次是手动录入的。

但是考虑到要计算好多点法线,第二次顶点数组是根据第一次三角形顶点序列自动生成的。此外,本例的UV坐标和切线没有太多的处理,贴图相关的功能还有待改善。

本文转自蓝鸥Unity3D培训。

相关主题