之前,因为工作需要,项目中需要动态生成很多的电线,不能事先让模型做好,更不能用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. linux上快速搭建宝塔面板来操作便捷功能

    关于宝塔 Linux版请确保纯净系统安装(支持CentOS.Ubuntu.Debian.Fedora.Deepin),Web端管理,QQ群及论坛技术支持一键LAMP/LNMP.创建网站FTP.数据库. ...

  2. 混合式应用开发之Cordova+vue(1)

    一.Cordova创建应用 cordova create oneApp Cordova创建应用出错 Cordova安装时不能使用cnpm 应该使用npm,cnpm虽然快但是后期出的错绝对比这省下来的时 ...

  3. ECC公钥格式详解

    本文首先介绍公钥格式相关的若干概念/技术,随后以示例的方式剖析DER格式的ECC公钥,最后介绍如何使用Java生成.解析和使用ECC公钥. ASN.1 Abstract Syntax Notation ...

  4. 继承自 DevExpress 17.2 的自定义控件如何在工具箱显示

    最近把DevExpress版本从13.1升级到了17.2,结果发现继承自DevExpress的自定义控件居然在工具箱中消失了,弄了两天还是没有任何头绪,部分自定义Dev控件可以正常出现,但大部分自定义 ...

  5. 用命令直接在两台ubuntu之间传输数据

    首先查看openssh-server是否启动: ps -e | grep ssh 如果没有任何提示则是没有启动: sudo /etc/init.d/ssh -start 启动进程.若提示找不到命令则需 ...

  6. 使用ffmpeg转码时遇到aac报错

    今天尝试用ffmpeg转一个视频的格式,结果报出这个错误: The encoder 'aac' is experimental but experimental codecs are not enab ...

  7. ES6(类)

    类的概念 1.基本定义 2.继承 继承如何传递参数?(super) 定义自己属性的时候调用 this 一定要在 super 之后(在继承关系中,子类的构造函数如果用 super 传递参数的过程中,su ...

  8. jQuery 学习笔记一

  9. Go 语言Map(集合)

    Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...

  10. 全新 Kali Linux 系统安装指南

    Kali Linux 系统可以说是在安全测试方面最好的开箱即用的 Linux 发行版.Kali 下的很多工具软件都可以安装在大多数的 Linux 发行版中,Offensive Security 团队在 ...