之前,因为工作需要,项目中需要动态生成很多的电线,不能事先让模型做好,更不能用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. Uncaught (in promise) TypeError:的错误

    1.错误 创建一个vue实例,在data定义一些变量,如activityTime. 在methods里面用了axios发送请求. 在then的回调里使用this.activityTime 报错! 2. ...

  2. Echarts 中国地图各个省市自治区自定义颜色

    前言 最近接了一个外包的项目,其中有个需求是这样的, 需要展示一个中国的统计地图,要求每个省市区都是不一样的颜色,必须特别区分开.以及隐藏南海部分. 看了Echats相关文档,发现有类似的demo,但 ...

  3. SpringMVC与Zookeeper、Dubbo使用示例

    Dubbo整合Zookeeper和spring示例程序 1.Dubbo架构 本篇文章基于dubbox,使用dubbo应该也可以正常运行. 我认为想讲清楚一个任何一个技术框架,首先熟悉架构是非常有必要的 ...

  4. 我在 Ubuntu 下使用 Sublime 编写 python 代码时遇到并解决的问题

    Ubuntu 下 Sublime 无法输入中文 解决方法如下: sudo apt-get update && sudo apt-get upgrade 克隆项目到本地 : git cl ...

  5. MySQL 连接的使用

    MySQL 连接的使用 在前几章节中,我们已经学会了如果在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据. 本章节我们将向大家介绍如何使用 MySQL 的 JOIN ...

  6. Docker仓库

    仓库是集中存放镜像文件的场所.有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分.实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(t ...

  7. Python-Jupyter Notebook使用技巧

    0. 体验与安装 首先可以通过Jupyter Notebook体验这个链接体验一下Jupyter Notebook. 首先安装ipython:pip3 install ipython 然后安装Jupy ...

  8. 利用LogParser将IIS日志插入到数据库

    利用LogParser将IIS日志插入到数据库 上面的博文是定制一个计划任务来将log日志定时的导入数据库      下面这篇博文是用cmd指令将日志导入到一张sql表中,是一次性操作   Log P ...

  9. 【Unity Shader】自定义材质面板的小技巧

    写在前面 之前遇到过一些朋友问怎么在材质面板里定义类似于bool这种变量,控制一些代码的执行.我们当然可以写一个C#文件来自定义材质面板,就像Unity为Standard Shader写材质面板一样( ...

  10. 剑指Offer——企业级项目中分层的含义与依据及多态的优势

    剑指Offer--企业级项目中分层的含义与依据及多态的优势   关于以上两点,由于项目经验较少,自己不是很明白,特整理如下. 常见分层架构模式 三层架构 3-tier architecture   微 ...