时间:2021-05-20
前言
这几天琢磨着开发个个人作品的时候,发现原来Unity3D官方没有提供圆锥体的创建功能,就自己做了个编辑器扩展。鉴于之前搜索Mesh编程的时候很少有博客把自己的算法讲清楚,这里我抛砖引玉,尽我所能为一些初学者提供参考,当然,算法未必优,如有更好的算法并乐意知会我则不胜感激,我是大龄转行Unity3D开发,一路行来都是自己琢磨,比较辛苦,先行谢过。
软件环境
Win10 + Unity3D 2017.3.0f3
正文
基本思路是以原点为圆锥体底部圆的中心点,以其正上方1单元处的点为圆锥体锥尖顶点,其他点参照Cylinder为分布在半径为0.5单元的圆上,每20度一个点,这样总共加起来的顶点数量是38个,三角形索引数组数量是108个(锥体可以看作底部圆心上移,所以这两部分的三角形数量是相等的,而底部每20度一个点,那么就有18个三角形,所以结果就是18∗3∗2=10818∗3∗2=108)。
下面开始逐步分解实现。
编辑器扩展
首先,扩展编辑器,在GameObject/3D Object下新建一个Cone菜单,为了假装是亲生的,就和Cube等原生菜单放在一起好了。
[MenuItem("GameObject/3D Object/Cone",false,priority = 7)]public static void CreateCone(){ SpawnConeInHierarchy();}这里主要就是利用MenuItem特性来实现的,其中false表示该菜单不需要有效性验证,priority=7控制菜单显示的位置,可以参考这里: Unity扩展Hierachry的右键菜单
方便起见,我把图贴下面:
接下来实现SpawnConeInHierarchy方法:
private static void SpawnConeInHierarchy() { Transform[] selections = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.ExcludePrefab); if (selections.Length <= 0) { GameObject cone = new GameObject("Cone"); cone.transform.position = Vector3.zero; cone.transform.rotation = Quaternion.identity; cone.transform.localScale = Vector3.one; //SetMesh(cone); return; } foreach (Transform selection in selections) { GameObject cone = new GameObject("Cone"); cone.transform.SetParent(selection); cone.transform.localPosition = Vector3.zero; cone.transform.localRotation = Quaternion.identity; cone.transform.localScale = Vector3.one; //SetMesh(cone); } }这里分两种情况,如果没有在Hierarchy面板选中任何物体,那么就在根目录下生成一个名字为”Cone”的GameObject,如果有选中物体,则生成的”Cone”会变为选中项的子物体。
PS:这里有个Bug,如果同时选中了多个物体,又是采用的Hierarchy面板右键菜单的方式,那么会在每个选中物体下都生成与选中物体数量相同的子物体,见下图。这个Bug应该不仅限于版本2017.3,因为我在网上有搜到一个同情况的帖子,时间是2016年8月。
目前这个Bug我已经提交给官方确认了,他们已转交给QA,不过不影响使用,避免办法就是不用右键菜单,而是点击菜单栏”GameObject”下的菜单。
到此为止,我们已经扩展了编辑器菜单,但是生成出来的是空物体,接下来我们实现SetMesh方法以创建Mesh,让圆锥体显示出来。
创建Mesh
分两部,首先绘出底部的圆。
绘制圆形底部
圆心已经确定为原点,半径为0.5f,圆上分布共20个点,那么每个点的坐标就可以用三角函数算出。
private static void SetMesh(GameObject go) { if (null == go) return; //仿Cylinder参数 float myRadius = 0.5f; int myAngleStep = 20; Vector3 myTopCenter = new Vector3(0, 1, 0); Vector3 myBottomCenter = Vector3.zero; //构建顶点数组和UV数组 //每20度一个顶点,再加上圆心,得出顶点数组长度 Vector3[] myVertices = new Vector3[360 / myAngleStep + 1]; //因为uv数组和顶点数组是一一对应的,所以这里同时计算uv数组 Vector2[] myUV = new Vector2[myVertices.Length]; //将圆心作为第一个顶点,对应的uv设置为贴图正中 myVertices[0] = myBottomCenter; myUV[0] = new Vector2(0.5f, 0.5f); //循环计算其他顶点坐标 for (int i = 1; i <= myVertices.Length / 2; i++) { float curAngle = i * myAngleStep * Mathf.Deg2Rad; float curX = myRadius * Mathf.Cos(curAngle); float curZ = myRadius * Mathf.Sin(curAngle); myVertices[i] = new Vector3(curX, 0, curZ); //顶点坐标范围是[-0.5,0.5],而uv坐标范围是[0,1],所以要进行转换 myUV[i] = new Vector2(curX + 0.5f, curZ + 0.5f); }接下来,构建三角形索引数组,19个顶点,共18个三角形,所以数组长度是18 * 3 = 54。
int[] myTriangle = new int[(myVertices.Length - 1) * 3]; //每三个索引(即顶点数组中的顶点索引值)为一个三角形索引组 for (int i = 0; i <= myTriangle.Length - 3; i = i+3) { //每组都以圆心起始 myTriangle[i] = 0; //为能从圆锥底部看见物体,这里按逆时针顺序排列,也就是(0 1 2 0 2 3...) myTriangle[i + 1] = i / 3 + 1; //最后一个三角形时终点索引应为1 myTriangle[i + 2] = i + 2 == myTriangle.Length / 2 - 1 ? 1 : i / 3 + 2; } }最后,分配mesh,赋值材质后就可以看到一个圆形物体了。
//构建mesh Mesh myMesh = new Mesh(); myMesh.name = "Cone"; myMesh.vertices = myVertices; myMesh.triangles = myTriangle; myMesh.uv = myUV; myMesh.RecalculateBounds(); myMesh.RecalculateNormals(); myMesh.RecalculateTangents(); //分配mesh MeshFilter mf = go.AddComponent<MeshFilter>(); mf.mesh = myMesh; //分配材质 MeshRenderer mr = go.AddComponent<MeshRenderer>(); Material myMat = new Material(Shader.Find("Standard")); mr.sharedMaterial = myMat;因为底部没光照,所以看起来是黑的,另外,上面的代码是我从最终代码中手动修改得到的,可能有错误,只是用于理解思路,完整代码会在最后给出。
完善锥体
底部圆既然已经绘制成功,锥体可以理解为将圆心上移即可,在顶点数量上,三角形索引数组上都相当于double了一份即可。
这里有个情况说明一下,我本来是想共用圆上顶点的,这样整个锥体的顶点数就是20,但经过测试是不可以的,我参考了Cube,顶点数是24,说明不同面的顶点是不能共用的,可能是因为法线方向等因素吧。
修改后的完整代码如下:
PS:这里的uv设置比较简单,所以对贴图也特定要求,不然图片会比较扭曲,需要的朋友可以自行修改。
结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
好多unity3d的爱好者,可以把游戏导出为linux的版本,让unity3d游戏在ubuntu下跑起来...1、打开自己的unity3d游戏项目,File--
unity3d中通过对一个按钮的创建使用,从而了解unity3d中UI的使用。软件名称:Unityformacv5.0.0b1苹果电脑版软件大小:1.66GB更
之前简单介绍了一下unity3d中的光源分类,默认情况下的光源是白色的。对于需要创建绚丽或者唯美的游戏,实在不妥。可是很好,unity3d中的光源经过合适的调整
Unity3D怎么显示网格,我们学习Unity3D的时候,教程老师的页面里面的视图窗口有网格,我们怎么漆黑一片,我们怎么显示网格呢软件名称:Unity3DPro
本文实例为大家分享了Unity3d简易五子棋源码,供大家参考,具体内容如下Unity3d部分对C#源码进行了改写简化:usingUnityEngine;usin