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 ...
随机推荐
- beta2
组员1:吴晓晖(组长) 过去两天完成了哪些任务 代码重构基本完成 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员2:陈锦谋 过去两天完成了哪些任务 重新制作图标 ...
- [软工课程博客] 求解第N个素数
任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...
- Mac安装Appium的Android环境
1.下载android sdk http://down.tech.sina.com.cn/page/45703.html 2.解压,配置环境变量 ANDROID_HOME=/Users/wp/ ...
- [转帖]在VMware ESXi服务器上配置NAT上网 需要学习一下。
http://blog.51cto.com/boytnt/1292487 在使用VMware workstation的时候,我们经常以NAT的方式配置虚拟机的网络,与桥接方式相比,这样配置可以让虚拟机 ...
- Oracle 12c 之前的版本路线图
- java8新特性(四)_Stream详解
之前写过一篇用stream处理map的文章,但是对stream没有一个整体的认识,这次结合并发编程网和ibm中介绍stream的文章进行一个总结,我会着重写对list的处理,毕竟实际工作中大家每天进行 ...
- SSH & Git
SSH基本用法 SSH服务详解 work with git branch some tips for git setup and git config git and github ssh servi ...
- 【刷题】HDU 5869 Different GCD Subarray Query
Problem Description This is a simple problem. The teacher gives Bob a list of problems about GCD (Gr ...
- CentOs 自带 PHP 之坑
在虚拟机上安装了CentOs6.5在上面安装了lnmp开发集成包(php7.1),对于之前没有任何开发经验的我来说,正常且安详滴在集成环境上开发着优雅的小bug. 然而我今天在Composer拉取代码 ...
- CentOS6.8下安装Nginx-1.9.15
1. 简介 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器. Nginx是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器,并在一个BS ...