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

前言

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

本文以自定义编译器菜单的方式,实现了Unity创建正二十面体的功能扩展。


博文首发:http://blog.csdn.net/duzixi


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




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


步骤一:

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


源代码:

[csharp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /// <summary>  
  2. /// Mesh网格编程 —— 点击拓展菜单,创建正二十面体  
  3. /// Created by 杜子兮(duzixi.com) 2015.2.20  
  4. /// www.lanou3g.com All Rights Reserved.  
  5. /// </summary>  
  6.   
  7. using UnityEngine;  
  8. using UnityEditor;          // 使用编译器类  
  9. using 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.         regular.name = name;                    // 根据参数命名  
  86.         regular.AddComponent<MeshFilter>();     // 添加MeshFilter组件  
  87.         regular.AddComponent<MeshRenderer>();   // 添加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<MeshFilter>().mesh = mesh; // 添加网格  
  96.     }  
  97.   
  98. }  


步骤二:

在菜单中选择

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

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


步骤三:

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


后语

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

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

但是考虑到要计算好多点法线,第二次顶点数组是根据第一次三角形顶点序列自动生成的。

此外,本例的UV坐标和切线没有太多的处理,贴图相关的功能还有待改善。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity是一款功能强大的游戏开发引擎,其中有一个重要的功能就是网格自定义。网格自定义是指开发者可以根据自己的需求,自定义游戏中的网格,在游戏中实现各种独特的地形、建筑等效果。 首先,Unity提供了一个网格编辑器,开发者可以使用该编辑器来创建和调整网格。编辑器中有各种工具,例如顶点编辑器、面编辑器、边编辑器等,可以帮助开发者对网格进行各种操作,比如添加、删除、移动、旋转等。 其次,Unity提供了丰富的网格组件,开发者可以将这些组件添加到游戏对象上,来实现各种效果。例如,Mesh Filter用于加载网格资源,Mesh Renderer用于渲染网格Mesh Collider用于检测碰撞等。 另外,Unity还支持脚本编程,开发者可以通过编写脚本来实现更加复杂的网格操作。例如,可以通过脚本控制网格的生成算法,实现动态生成地形的效果;还可以通过脚本控制网格的变形,实现形变效果等。 除了以上功能,Unity还支持导入外部的网格资源,开发者可以使用第三方建模工具创建好的网格,然后将其导入到Unity中使用。同时,Unity还支持多种网格文件格式的导入和导出,方便开发者与其他建模工具进行交互。 综上所述,Unity网格自定义功能强大且灵活,可以满足开发者对网格的各种需求,并且提供了丰富的工具和组件支持,以及脚本编程的灵活性。这使得开发者可以更加轻松地创建出独特而富有创意的游戏世界。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值