之前,因为工作需要,项目中需要动态生成很多的电线,不能事先让模型做好,更不能用LineRenderer之类的,因为画出来没有3D的效果,最主要是拐角的时候还容易破面,而我们要的是真真实实纯3D的电线,网上找了很多类似于画线的插件,但都没有我想要的效果,索性,我就自己想着动手写一个,这也是这个插件的由来。

之后也是工作上的问题,经常因为模型上的一些细微改动而重新导入模型,替换起来很麻烦,所以尝试着实现能在unity里改动模型的顶点,当然这个方法网上的例子较多,不过在我整合改进了之后,操作起来更加的方便,暂时还没有添加顶点以及删除顶点的功能,不过后续我会逐渐加入这些功能。

MeshEditor功能点一:3D网格线段作画


只需要给定起始点以及结束点的两个vector3,以及为其指定材质和半径,便可以画出一条线段,效果如下:

这里实现的方式是分别在起始点的位置画出一个六边形的面,两者相对之后,再分别将两个面对应的六个顶点相连并画出三角形:(部分代码)

bool trade = false;
//线段所在轴
float Xgap = Mathf.Abs(startPositon.x - endPosition.x);
float Ygap = Mathf.Abs(startPositon.y - endPosition.y);
float Zgap = Mathf.Abs(startPositon.z - endPosition.z); Vector3[] _Vertices = new Vector3[24];
if (Xgap >= Ygap && Xgap >= Zgap)
{
Vector3 middle;
//线段方向对调(有时候需要获取线段位置时必须获取它的开始位置)
if (startPositon.x < endPosition.x)
{
middle = startPositon;
startPositon = endPosition;
endPosition = middle;
trade = true;
}
//创建线段
_Vertices = new Vector3[24]
{
new Vector3(startPositon.x, startPositon.y, startPositon.z + radius),
new Vector3(startPositon.x, startPositon.y + Mathf.Sin(3.14f/180*30) * radius, startPositon.z + Mathf.Cos(3.14f/180*30) * radius),
new Vector3(startPositon.x, startPositon.y + Mathf.Sin(3.14f/180*60) * radius, startPositon.z + Mathf.Cos(3.14f/180*60) * radius),
new Vector3(startPositon.x, startPositon.y + radius, startPositon.z),
new Vector3(startPositon.x, startPositon.y + Mathf.Sin(3.14f/180*60) * radius, startPositon.z - Mathf.Cos(3.14f/180*60) * radius),
new Vector3(startPositon.x, startPositon.y + Mathf.Sin(3.14f/180*30) * radius, startPositon.z - Mathf.Cos(3.14f/180*30) * radius),
new Vector3(startPositon.x, startPositon.y, startPositon.z - radius),
new Vector3(startPositon.x, startPositon.y - Mathf.Sin(3.14f/180*30) * radius, startPositon.z - Mathf.Cos(3.14f/180*30) * radius),
new Vector3(startPositon.x, startPositon.y - Mathf.Sin(3.14f/180*60) * radius, startPositon.z - Mathf.Cos(3.14f/180*60) * radius),
new Vector3(startPositon.x, startPositon.y - radius, startPositon.z),
new Vector3(startPositon.x, startPositon.y - Mathf.Sin(3.14f/180*60) * radius, startPositon.z + Mathf.Cos(3.14f/180*60) * radius),
new Vector3(startPositon.x, startPositon.y - Mathf.Sin(3.14f/180*30) * radius, startPositon.z + Mathf.Cos(3.14f/180*30) * radius), new Vector3(endPosition.x, endPosition.y, endPosition.z + radius),
new Vector3(endPosition.x, endPosition.y + Mathf.Sin(3.14f/180*30) * radius, endPosition.z + Mathf.Cos(3.14f/180*30) * radius),
new Vector3(endPosition.x, endPosition.y + Mathf.Sin(3.14f/180*60) * radius, endPosition.z + Mathf.Cos(3.14f/180*60) * radius),
new Vector3(endPosition.x, endPosition.y + radius, endPosition.z),
new Vector3(endPosition.x, endPosition.y + Mathf.Sin(3.14f/180*60) * radius, endPosition.z - Mathf.Cos(3.14f/180*60) * radius),
new Vector3(endPosition.x, endPosition.y + Mathf.Sin(3.14f/180*30) * radius, endPosition.z - Mathf.Cos(3.14f/180*30) * radius),
new Vector3(endPosition.x, endPosition.y, endPosition.z - radius),
new Vector3(endPosition.x, endPosition.y - Mathf.Sin(3.14f/180*30) * radius, endPosition.z - Mathf.Cos(3.14f/180*30) * radius),
new Vector3(endPosition.x, endPosition.y - Mathf.Sin(3.14f/180*60) * radius, endPosition.z - Mathf.Cos(3.14f/180*60) * radius),
new Vector3(endPosition.x, endPosition.y - radius, endPosition.z),
new Vector3(endPosition.x, endPosition.y - Mathf.Sin(3.14f/180*60) * radius, endPosition.z + Mathf.Cos(3.14f/180*60) * radius),
new Vector3(endPosition.x, endPosition.y - Mathf.Sin(3.14f/180*30) * radius, endPosition.z + Mathf.Cos(3.14f/180*30) * radius)
};
}

同时,提供起点终点以及弯曲弧度还能画出一段曲线,效果如下:

这里实现的方式是从起点开始到终点分别以给定的弯曲值及分段值画出一系列线段:(部分代码)

//注:弧度越大,同时节点越少或是起始点与结束点距离越近,画出的曲线越不真实
if (length % 2 != 0) length += 1;
//曲线过渡点
Vector3 LostMedium;
Vector3 NewMedium;
//曲线平均衰减值
float xD = (endPosition.x - startPositon.x) / length;
float yD = (endPosition.y - startPositon.y) / length;
float zD = (endPosition.z - startPositon.z) / length;
//曲线减速衰减值
float XWeakValue = radian.x / (length / 2);
float YWeakValue = radian.y / (length / 2);
float ZWeakValue = radian.z / (length / 2);
//曲线弧度延伸值
float XBendingValue = 0;
float YBendingValue = 0;
float ZBendingValue = 0; GameObject _Line = new GameObject("Curve");
_Line.transform.localScale = Vector3.one;
_Line.transform.position = Vector3.zero;
_Line.transform.rotation = Quaternion.Euler(0, 0, 0); XBendingValue += radian.x;
YBendingValue += radian.y;
ZBendingValue += radian.z;
LostMedium = startPositon;
NewMedium = new Vector3(startPositon.x + xD + XBendingValue, startPositon.y + yD + YBendingValue, startPositon.z + zD + ZBendingValue);
Draw(LostMedium, NewMedium, lineMaterial, radius).transform.SetParent(_Line.transform);
//循环画线段
for (int i = 2; i <= length / 2; i++)
{
XBendingValue += (radian.x - XWeakValue * (i - 1));
YBendingValue += (radian.y - YWeakValue * (i - 1));
ZBendingValue += (radian.z - ZWeakValue * (i - 1));
LostMedium = NewMedium;
NewMedium = new Vector3(startPositon.x + xD * i + XBendingValue, startPositon.y + yD * i + YBendingValue, startPositon.z + zD * i + ZBendingValue);
Draw(LostMedium, NewMedium, lineMaterial, radius).transform.SetParent(_Line.transform);
}


MeshEditor功能点二:模型网格顶点篡改

为任意模型添加我们的模型网格编辑器脚本,我们就可以随意拖动顶点修改模型网格,编辑完成之后记得删除脚本,以保存修改,原模型不会被修改,最终改动的模型只是原模型的一个克隆体,所以不用担心会破坏网格,效果如下:

这里实现的方式是获取到模型的所有顶点,并创建可操作圆球与顶点一一对应,控制圆球的同时刷新模型顶点。

源码见第二篇博客

-----by MeshEditor

Unity插件 - MeshEditor(一) 3D线段作画 & 模型网格编辑器的更多相关文章

  1. Unity插件 - MeshEditor(三) 面片破碎&网格破碎

    网上的unity破碎插件很多,不过想着可以以自己的方式实现也不失为一种乐趣,虽然整体的表现性上显得有些差,但也并不会影响最终的效果,接下来我大致讲解一下破碎一个物体的流程,因为用到了协程计算碎片的原因 ...

  2. Unity插件 - MeshEditor(二) 模型网格编辑器(高级)

    源码已上传至github,并持续更新,链接请看底部.(本帖跟随github持续更新) 继先前的一篇MeshEditor之后,MeshEditor第二版发布,这次在先前的基础上加入了为模型新增顶点以及删 ...

  3. Unity插件 - MeshEditor(八)模型镜像特效

    将静态模型(带MeshFilter)按指定轴向.指定距离克隆一个镜像物体出来,思路很简单,将模型的顶点坐标按指定轴取反,并累加上设定的距离值,然后就完毕了!不过,因为镜像体的顶点镜像于之前模型的顶点, ...

  4. Unity插件 - MeshEditor(四) 模型融化特效

    现在的电影里有很多妖魔在死亡后身体逐渐融化并下滑最后化为一滩黑水的情景,本次出于兴趣大致研究了这个效果,原理是控制模型的顶点向一个方向坍塌,坍塌到最低点时再根据法线方向扩散形成黑水状. 第一步: 添加 ...

  5. Unity插件 - MeshEditor(七)变形动画骨骼及蒙皮

    MeshAnimation在物体的顶点比较多的情况下,悲剧是显而可见的,我一个一个的点选顶点肯定得累死,而且对于形态的调控不是很方便,应该说是很麻烦,要知道,骨骼动画因为有了骨骼以及蒙皮信息而有了灵魂 ...

  6. Unity插件 - MeshEditor(五) 网格顶点动画(变形动画)

    源码已上传至github,并持续更新,链接请看底部.(本帖跟随github持续更新) 网格顶点动画(变形动画)是针对于物体的形状可以随意变换并记录为关键帧的动画,虽然模型的顶点数据还是应该交给GPU绘 ...

  7. Unity插件 - MeshEditor(六) 变形动画状态机

    变形动画状态机--MeshAnimator,是针对MeshAnimation的状态管理器,有大量类似Unity animator的功能,但MeshAnimator操作会更加简便,更加直观,居家旅(zh ...

  8. Unity 3d导入3dMax模型 产生若干问题

    Unity 3d导入3dMax模型 会产生若干问题,按照官方 的说明,将max 模型导成fbx文件 导入untiy似乎也不能解决 1.x轴向偏转3dmax模型导入后自动有一个x轴270度的偏转,巧合的 ...

  9. 关于Unity中NGUI的3D角色血条的实现

    首先要到Unity的Assets Store里面去下载一个扩展的Package叫NGUI HUD Text v1.13(81),注意如果没有安装NGUI就必须先安装NGUI插件,否则会用不了,因为HU ...

随机推荐

  1. tree的遍历--广度优先遍历

    一.二叉树demo var tree = { value: '一', left: { value: '二', left: { value: '四', right: { value: '六' } } } ...

  2. MySQL数据类型DECIMAL用法

    MySQL DECIMAL数据类型用于在数据库中存储精确的数值.我们经常将DECIMAL数据类型用于保留准确精确度的列,例如会计系统中的货币数据. 要定义数据类型为DECIMAL的列,请使用以下语法: ...

  3. Docker常见仓库CentOS

    CentOS 基本信息 CentOS 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致. 该仓库提供了 CentOS 从 5 ~ 7 各个版本的镜像. 使用方法 默认会启动一个 ...

  4. RDO Stack: Failed connect to server

    Issue: When you create an instance, but cannot connect to the VNC Server because of the error messag ...

  5. Bootstrap3 代码-变量

    通过 <var> 标签标记变量. y = mx + b <var>y</var> = <var>m</var><var>x< ...

  6. vue关于数组使用的坑

    关于数组使用的坑 https://vuejs.org/v2/guide/list.html#Caveats 简言之, 不要使用a[i] = v 的形式, 用a.splice(i, 1, v), 或Vu ...

  7. ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决

    ScrollView嵌套ListView后,进入页面不从顶部开始显示的问题解决 首先,正常情况下,如果在ScrollView里嵌套ListView后,会发现ListView只显示1条数据 那么,为了解 ...

  8. Android二维码扫描、生成

    Android二维码扫描.生成 现在使用二维码作为信息的载体已经越来越普及,那么二维码的生成以及扫描是如何实现的呢 google为我们提供了zxing开源库供我们使用 zxing GitHub源码地址 ...

  9. Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api

    联系人实体中有个特殊的字段parentcustomerid 在通过web api创建或更新记录时,如果在给这个字段赋值时当做查找字段对待的话,那你就会遇到问题了,报错信息如下 正确的赋值方式如下

  10. Android 开发环境的搭建(新环境)

    最近想往Android 转型,所以又重新捡起Android学习.看了一下各位大神的文章,说的比较乱,因为版本不一样所以搭建过程也不一样,我在这里说一下最简单快捷的方式.(PS:那时候搭建环境好复杂啊, ...