网格绘制主要用是对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 网格 绘制的更多相关文章

  1. Unity网格合并_材质合并

    [转]Unity网格合并_材质合并 原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网 ...

  2. 【转】Unity网格合并_材质合并

    原帖请戳:Unity网格合并_材质合并 写在前面: 从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装, ...

  3. Unity Gizmos绘制指定长宽的网格

    using UnityEngine; using System.Collections; public class GridMap : MonoBehaviour { ; //宽度 ; //长度 vo ...

  4. ICEM(2)—机翼翼稍网格绘制

    有时我们需要观察翼尖涡,这就需要将机翼全部被网格包围.但是网上比较多的教程都是机翼边缘即为网格边缘,机翼位于网格内部的不多.若是直接将网格拉伸,则会产生结构和非结构网格交错的情况.下面是绘制步骤 1. ...

  5. Unity 网格合并

    从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装,那么需要合并SkinnedMeshRenderer, ...

  6. unity EditorGUILayer绘制报错

    最近在开发一个可视化工具的时候,遇到了一个代码错误,小小的记录一下 具体的报错信息:ArgumentException: Getting control 0's position in a group ...

  7. unity gizmo绘制圆形帮助调试

    using UnityEngine; using System.Collections; using System; public class LearnGrazio : MonoBehaviour ...

  8. unity中绘制战争迷雾

    接上一篇中说的游戏,我们已经实现了client.host上的一个物体可见不可见的行为.之后我们可以加入类似检查两个单位之间的距离.或是两个单位之间有无阻挡物来进一步实现游戏机制. 在这篇随笔中我会首先 ...

  9. ICEM(1)—边界结构网格绘制

    以两个圆为例 1. geometry→ create curve→ 选择圆,随便画两个圆 2. block下选择create block,选择第一项,initial block,设置改为2D Plan ...

随机推荐

  1. 小学四则运算APP 第一个冲刺 第二天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第一次冲刺阶段时间:11.17~11.27 本次程序是为了解决上次判断的问题,但是还是出现新的问题页面无法调整,需要进行改进 本次改进代码 ...

  2. CI框架 default_controller 如何设置为:'目录/Controller' 转

    闲谈 前几天,我的室友发现了一个问题:CI框架的Router.php文件的default_controller设置为application\controllers文件下的 一级PHP文件名 就可以,设 ...

  3. [转帖]Windows 内置端口转发功能

    如何在Windows中使用netsh命令进行端口转发 https://www.freebuf.com/articles/system/176889.html 早上自己做了下实验,的确可以.linux下 ...

  4. Windows 2012r2 以及以上版本远程提示错误的解决方法

    部分机器远程时会提示如图: 其实解决问题非常简单 .... 为了防止不会操作 完整的截图展示. 服务器下面进行处理 打开我的电脑 属性 打开远程设置 将框中的选项取消掉 然后就可以了.

  5. 新版 Chrome Ajax 跨域调试

    一.前言 web 开发中 Ajax 是十分常见的技术,但是在前后端使用接口对接的调试过程中不可避免会碰到跨域问题.今天我给大家介绍一个十分简单有效的方法. 跨域经典错误 二.Chrome 跨域设置 首 ...

  6. spring中的传播性 个人认为就是对方法的设置 其作用能传播到里面包含的方法上

    spring中的传播性 个人认为就是对方法的设置 其作用能传播到里面包含的方法上

  7. BZOJ1815 SHOI2006有色图(Polya定理)

    置换数量是阶乘级别的,但容易发现本质不同的点的置换数量仅仅是n的整数拆分个数,OEIS(或者写个dp或者暴力)一下会发现不是很大,当n=53时约在3e5左右. 于是暴力枚举点的置换,并且发现根据点的置 ...

  8. 用css绘制图形

    巧用css的border-radius属性,也能绘制出好看的图形 html部分 <!DOCTYPE html><html> <head> <meta char ...

  9. 【NOIP 2018】保卫王国(动态dp / 倍增)

    题目链接 这个$dark$题,嗯,不想说了. 法一:动态$dp$ 虽然早有听闻动态$dp$,但到最近才学,如果你了解动态$dp$,那就能很轻松做出这道题了.故利用这题在这里科普一下动态$dp$的具体内 ...

  10. Problem A: 种树 解题报告

    Problem A: 种树 Description 很久很久以前,一个蒟蒻种了一棵会提问的树,树有\(n\)个节点,每个节点有一个权值,现在树给出\(m\)组询问,每次询问两个值:树上一组点对\((x ...