网格绘制主要用是对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. beta2

    组员1:吴晓晖(组长) 过去两天完成了哪些任务 代码重构基本完成 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员2:陈锦谋 过去两天完成了哪些任务 重新制作图标 ...

  2. [软工课程博客] 求解第N个素数

    任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...

  3. Mac安装Appium的Android环境

    1.下载android sdk http://down.tech.sina.com.cn/page/45703.html   2.解压,配置环境变量   ANDROID_HOME=/Users/wp/ ...

  4. [转帖]在VMware ESXi服务器上配置NAT上网 需要学习一下。

    http://blog.51cto.com/boytnt/1292487 在使用VMware workstation的时候,我们经常以NAT的方式配置虚拟机的网络,与桥接方式相比,这样配置可以让虚拟机 ...

  5. Oracle 12c 之前的版本路线图

  6. java8新特性(四)_Stream详解

    之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行 ...

  7. SSH & Git

    SSH基本用法 SSH服务详解 work with git branch some tips for git setup and git config git and github ssh servi ...

  8. 【刷题】HDU 5869 Different GCD Subarray Query

    Problem Description This is a simple problem. The teacher gives Bob a list of problems about GCD (Gr ...

  9. CentOs 自带 PHP 之坑

    在虚拟机上安装了CentOs6.5在上面安装了lnmp开发集成包(php7.1),对于之前没有任何开发经验的我来说,正常且安详滴在集成环境上开发着优雅的小bug. 然而我今天在Composer拉取代码 ...

  10. CentOS6.8下安装Nginx-1.9.15

    1. 简介 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器. Nginx是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器,并在一个BS ...