Unity 网格 绘制
网格绘制主要用是对Mesh进行操作,通过对vertex和triangles进行操作生成对应的面片;
这里首先得用到一个类:Triangulator(根据vertex生成triangles数组)
using UnityEngine;
using System.Collections.Generic; public class Triangulator
{
private static List<Vector2> points;
private static Vector3 cameraPosition; public static Vector2[] ToVector2(Vector3[] m_points)
{
Vector2[] vertices2d = new Vector2[m_points.Length];
for (int i = ; i < m_points.Length; i++)
{
Vector3 pos = m_points[i];
vertices2d[i] = new Vector2(pos.x, pos.z);
}
return vertices2d;
} public static int[] Triangulate(Vector2[] m_points, Vector3 m_cameraPosition)
{
points = new List<Vector2>(m_points);
cameraPosition = m_cameraPosition; List<int> indices = new List<int>(); int n = points.Count;
if (n < )
return indices.ToArray(); int[] V = new int[n];
if (Area() > )
{
for (int v = ; v < n; v++)
V[v] = v;
}
else
{
for (int v = ; v < n; v++)
V[v] = (n - ) - v;
} int nv = n;
int count = * nv;
for (int m = , v = nv - ; nv > ;)
{
if ((count--) <= )
break; int u = v;
if (nv <= u)
u = ;
v = u + ;
if (nv <= v)
v = ;
int w = v + ;
if (nv <= w)
w = ; if (Snip(u, v, w, nv, V))
{
int a, b, c, s, t;
a = V[u];
b = V[v];
c = V[w];
indices.Add(a);
indices.Add(b);
indices.Add(c);
m++;
for (s = v, t = v + ; t < nv; s++, t++)
V[s] = V[t];
nv--;
count = * nv;
}
} bool reversFlag = true;
int i0 = indices[];
int i1 = indices[];
int i2 = indices[];
Vector3 pos0 = new Vector3(points[i0].x, 0f, points[i0].y);
Vector3 pos1 = new Vector3(points[i1].x, 0f, points[i1].y);
Vector3 pos2 = new Vector3(points[i2].x, 0f, points[i2].y);
Vector3 v1 = pos1 - pos0;
Vector3 v2 = pos2 - pos1;
Vector3 crossVec = Vector3.Cross(v1, v2);
if (Vector3.Dot(cameraPosition, crossVec) > )
{
reversFlag = false;
}
if (reversFlag)
{
indices.Reverse();
} return indices.ToArray();
} private static float Area()
{
int n = points.Count;
float A = 0.0f;
for (int p = n - , q = ; q < n; p = q++)
{
Vector2 pval = points[p];
Vector2 qval = points[q];
A += pval.x * qval.y - qval.x * pval.y;
}
return (A * 0.5f);
} private static bool Snip(int u, int v, int w, int n, int[] V)
{
int p;
Vector2 A = points[V[u]];
Vector2 B = points[V[v]];
Vector2 C = points[V[w]];
if (Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))))
return false;
for (p = ; p < n; p++)
{
if ((p == u) || (p == v) || (p == w))
continue;
Vector2 P = points[V[p]];
if (InsideTriangle(A, B, C, P))
return false;
}
return true;
} private static bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
{
float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
float cCROSSap, bCROSScp, aCROSSbp; ax = C.x - B.x; ay = C.y - B.y;
bx = A.x - C.x; by = A.y - C.y;
cx = B.x - A.x; cy = B.y - A.y;
apx = P.x - A.x; apy = P.y - A.y;
bpx = P.x - B.x; bpy = P.y - B.y;
cpx = P.x - C.x; cpy = P.y - C.y; aCROSSbp = ax * bpy - ay * bpx;
cCROSSap = cx * apy - cy * apx;
bCROSScp = bx * cpy - by * cpx; return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
}
}
Triangulator.cs
然后我们创建一个脚本:DrawMesh.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System; public class DrawMesh : MonoBehaviour
{
#region 公共变量
/// <summary>
/// 绘制模式,间断、连续
/// </summary>
public enum DrawMeshModel { Intermittently, Continuously }; /// <summary>
/// 线段材质、网格材质
/// </summary>
public Material lineMat, meshMat; /// <summary>
/// 绘制模式
/// </summary>
public DrawMeshModel drawModel = DrawMeshModel.Intermittently; public float lineWidth = 0.5f;//线段宽度
public float meshAlpha = 0.2f;//网格透明度
#endregion #region 私有变量
Vector3[] points = new Vector3[]; LineRenderer lineTemp;
GameObject lineObject; MeshFilter meshFilter;
GameObject meshObject;
Mesh mesh;//网格 Ray ray;
RaycastHit hit; /// <summary>
/// 记录上一点位置
/// </summary>
Vector3 last = Vector3.zero;
#endregion void Start()
{
lineObject = new GameObject("LineGameObject");
lineTemp = lineObject.AddComponent<LineRenderer>();
lineTemp.SetWidth(lineWidth, lineWidth);
lineTemp.material = lineMat; meshObject = new GameObject("MeshGameObject");
meshFilter = meshObject.AddComponent<MeshFilter>();
meshObject.AddComponent<MeshRenderer>();
meshObject.GetComponent<Renderer>().material = meshMat;
Color tempColor = meshMat.color;
tempColor.a = meshAlpha;
meshMat.color = tempColor;
mesh = new Mesh(); lineObject.SetActive(false);
} void Update()
{
if (Input.GetMouseButton() && drawModel == DrawMeshModel.Continuously
|| Input.GetMouseButtonDown() && drawModel == DrawMeshModel.Intermittently)
{
if (!lineObject.activeInHierarchy)
lineObject.SetActive(true); ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (drawModel == DrawMeshModel.Continuously)
{
if (last == Vector3.zero)
{
last = hit.point;
return;
}
else if (Vector3.Distance(last, hit.point) < 1f)
{
return;
}
last = hit.point;
} Array.Resize(ref points, points.Length + );
points[points.Length - ] = hit.point + new Vector3(, 0.25f, );
lineTemp.SetVertexCount(points.Length);
lineTemp.SetPosition(points.Length - , points[points.Length - ]); if (points.Length > )
{
mesh.vertices = points;
mesh.triangles = Triangulator.Triangulate(Triangulator.ToVector2(points), Camera.main.transform.position);
meshFilter.mesh = mesh;
}
}
}
}
}
将DrawMesh脚本放置到物体上,给LineRenderer和Mesh赋上材质,这里我创建了一个枚举:DrawMeshModel;
通过选择Draw Model为Intermittently进行点击绘图,选择Continuously进行连续绘图;
设置线段宽度Line Width,网格透明度Mesh Alpha;

最后通过鼠标在Collider上绘制Mesh形状。
最终效果1:


最终效果2:


截图和GIF并非同一次画的,录的视频没上传成功,只好转成了gif,另外又截了图。
Unity 网格 绘制的更多相关文章
- Unity网格合并_材质合并
[转]Unity网格合并_材质合并 原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网 ...
- 【转】Unity网格合并_材质合并
原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装, ...
- Unity Gizmos绘制指定长宽的网格
using UnityEngine; using System.Collections; public class GridMap : MonoBehaviour { ; //宽度 ; //长度 vo ...
- ICEM(2)—机翼翼稍网格绘制
有时我们需要观察翼尖涡,这就需要将机翼全部被网格包围.但是网上比较多的教程都是机翼边缘即为网格边缘,机翼位于网格内部的不多.若是直接将网格拉伸,则会产生结构和非结构网格交错的情况.下面是绘制步骤 1. ...
- Unity 网格合并
从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装,那么需要合并SkinnedMeshRenderer, ...
- unity EditorGUILayer绘制报错
最近在开发一个可视化工具的时候,遇到了一个代码错误,小小的记录一下 具体的报错信息:ArgumentException: Getting control 0's position in a group ...
- unity gizmo绘制圆形帮助调试
using UnityEngine; using System.Collections; using System; public class LearnGrazio : MonoBehaviour ...
- unity中绘制战争迷雾
接上一篇中说的游戏,我们已经实现了client.host上的一个物体可见不可见的行为.之后我们可以加入类似检查两个单位之间的距离.或是两个单位之间有无阻挡物来进一步实现游戏机制. 在这篇随笔中我会首先 ...
- ICEM(1)—边界结构网格绘制
以两个圆为例 1. geometry→ create curve→ 选择圆,随便画两个圆 2. block下选择create block,选择第一项,initial block,设置改为2D Plan ...
随机推荐
- 云平台项目--学习经验--回调函数中call和apply
Js中可以通过call和apply来代替另一个对象调用一个方法,将一个函数对象上下文从初始上下文改变为thisObj指定的新对象.简而言之,改变函数执行的上下文,而call和apply的基本区别在于他 ...
- 我的IT未来
关于IT这个行业,我是持欣赏态度的,毕竟发展很快,对人们生活的改变也很大,所以,作为一个从事IT的人士,我很自豪. 读了刘先生的文章,我发现以前自己做的太少了,虽然偶尔也会吐血写程序,但还是太少了.以 ...
- ElasticSearch 2 (13) - 深入搜索系列之结构化搜索
ElasticSearch 2 (13) - 深入搜索系列之结构化搜索 摘要 结构化查询指的是查询那些具有内在结构的数据,比如日期.时间.数字都是结构化的.它们都有精确的格式,我们可以对这些数据进行逻 ...
- [转帖] 常见的cmd命令
记录一下 后期用的到. ------------ 1. Echo :显示当前ECHO的状态:ECHO ON 或者ECHO OFF .2. ECHO ON :ECHO状态设为ON,将显示命令行(如每行前 ...
- Java反射的用法
Class类 在Java中,每个class都有一个相应的Class对象.也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息. 反射 ...
- MT【107】立体几何中用阿波罗尼乌斯圆的一道题
分析:利用内外圆知识知道,B,C两点到 AD 的距离$\le4$. 利用体积公式$V=\frac{1}{3}S_{截面}|AD|\le2\sqrt{15}$
- 【题解】 bzoj4004: [JLOI2015]装备购买 (线性基)
bzoj4004,戳我戳我 Solution: 裸的线性基,这没啥好说的,我们说说有意思的地方(就是我老是wa的地方) Attention: 这题在\(luogu\),上貌似不卡精度,\(bzoj\) ...
- Java Socket/HttpURLConnection读取HTTP网页
以读取百度的http网页为例.如果知道了IP地址和端口,然后新建一个Socket,就直接去读百度的首页,根本没反应,原因是www.baidu.com是以http协议传输的,而现在要以Socket原始的 ...
- Ansible批量在远程主机执行命令
Ansible直接执行远程命令,不用ssh登陆交互执行. 如下: ansible all -i 192.168.199.180, -m shell -a "ifconfig" -u ...
- 德国GG了
我想起了今年ZJOI 这就是生活啊,伤悲总是要面对的