Unity中用Mesh画一个圆环(二)
中目标-生成完整面
在之前的内容中我们已经成功生成了一个面,接下来我们要生成剩下的面就很容易了。
我们把之前生成的面当作顶面,接着我们来生成底面。
还记得前面说过\(\color{#1E90FF}{Depth}\)这个参数用来控制深度,也就是顶面和地面之间的距离,放到坐标系中就是控制Z的位置。
底面和顶面的顶点生成方法是一样的,唯一不同的地方就是Z轴的不同。 我们只要用生成顶面的方法改下Z坐标,就可以得到底面了。
//下
for (int i = 0; i <= NumberOfSides; i++)
{
float angle = 180 - i * incrementAngle;
float innerX = (Radius - Thickness) * Mathf.Cos(angle * Mathf.Deg2Rad);
float innerY = (Radius - Thickness) * Mathf.Sin(angle * Mathf.Deg2Rad);
vertexList.Add(new Vector3(innerX, innerY, -1 * Depth / 2));
float outsideX = Radius * Mathf.Cos(angle * Mathf.Deg2Rad);
float outsideY = Radius * Mathf.Sin(angle * Mathf.Deg2Rad);
vertexList.Add(new Vector3(outsideX, outsideY, - 1 * Depth / 2));
}
三角形索引的生成和之前也是一样的,不同的是一开始的方向,因为顶面的法线是向上的,而底面的法线是向下的:
direction = 1;
startIndex += (NumberOfSides + 1) * 2;
for (int i = 0; i < NumberOfSides * 2; i++)
{
int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex);
direction *= -1;
for (int j = 0; j < triangleIndexs.Length; j++)
{
triangleList.Add(triangleIndexs[j]);
}
}
至于UV索引则设置和顶面的一样即可。
其实生成顶面和底面之后,大部分的工作已经完成了,这时候我们已经生成了我们需要的所有顶点。前后左右也只是用现有的这些顶点进行生成。
我们前面生成的圆柱体是基于圆生成的,如果我们改成基于贝塞尔生成的那也是可以的。
修改方法很简单,就是改下生成顶点时的过程就好了,其他的不需要动。
具体过程直接看代码吧,包看包懂。
当然下面的代码是为了方面理解所以写得冗余,如果用到项目中建议优化下,不然会被主程打的。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//[RequireComponent(typeof(MeshFilter))]
//[RequireComponent(typeof(MeshRenderer))]
[ExecuteInEditMode]
public class DrawArch : MonoBehaviour
{
public float Radius = 20.0f; //外圈的半径
public float Thickness = 10.0f; //厚度,外圈半径减去内圈半径
public float Depth = 1.0f; //厚度
public int NumberOfSides = 30; //由多少个面组成
public float DrawArchDegrees = 90.0f; //要绘画多长
public Vector2[] bezierPoints = new Vector2[4];
public Material archMaterial = null;
private int VertexCountOneSide = 0; //生成一面所需的顶点数
private Mesh mesh = null;
private float incrementAngle = 0;
private List<Vector3> vertexList = new List<Vector3>();
private List<int> triangleList = new List<int>();
private List<Vector2> uvList = new List<Vector2>();
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
}
void GenerateMesh()
{
VertexCountOneSide = (NumberOfSides + 1) * 2;
incrementAngle = DrawArchDegrees / NumberOfSides;
GenerateVertex();
GenerateTriangleIndex();
GenerateUV();
mesh.vertices = vertexList.ToArray();
mesh.uv = uvList.ToArray();
mesh.triangles = triangleList.ToArray();
mesh.RecalculateNormals();
gameObject.GetComponent<MeshFilter>().mesh = mesh;
gameObject.GetComponent<MeshRenderer>().material = archMaterial;
}
//生成顶点坐标
void GenerateVertex()
{
//上
vertexList.Clear();
for (int i = 0; i <= NumberOfSides; i++)
{
//float[] points = GetCirclePoint(Radius - Thickness, i);
//vertexList.Add(new Vector3(points[0], points[1], Depth / 2));
//points = GetCirclePoint(Radius, i);
//vertexList.Add(new Vector3(points[0], points[1], Depth / 2));
float[] points = GetBezierPoint(i);
vertexList.Add(new Vector3(points[0], points[1], Depth / 2));
points = GetBezierPoint(i);
vertexList.Add(new Vector3(points[0] - 1, points[1], Depth / 2));
}
//下
for (int i = 0; i <= NumberOfSides; i++)
{
//float[] points = GetCirclePoint(Radius - Thickness, i);
//vertexList.Add(new Vector3(points[0], points[1], -1 * Depth / 2));
//points = GetCirclePoint(Radius, i);
//vertexList.Add(new Vector3(points[0], points[1], -1 * Depth / 2));
float[] points = GetBezierPoint(i);
vertexList.Add(new Vector3(points[0], points[1], -1 * Depth / 2));
points = GetBezierPoint(i);
vertexList.Add(new Vector3(points[0] - 1, points[1], -1 * Depth / 2));
}
//前
for (int i = 0; i <= NumberOfSides * 2 ; i += 2)
{
vertexList.Add(vertexList[i]);
vertexList.Add(vertexList[i + VertexCountOneSide]);
}
//后
for (int i = 0; i <= NumberOfSides * 2; i += 2)
{
vertexList.Add(vertexList[i + 1]);
vertexList.Add(vertexList[i + VertexCountOneSide + 1]);
}
//左
vertexList.Add(vertexList[0]);
vertexList.Add(vertexList[1]);
vertexList.Add(vertexList[VertexCountOneSide + 0]);
vertexList.Add(vertexList[VertexCountOneSide + 1]);
//右
vertexList.Add(vertexList[VertexCountOneSide -2]);
vertexList.Add(vertexList[VertexCountOneSide - 1]);
vertexList.Add(vertexList[VertexCountOneSide * 2 - 2]);
vertexList.Add(vertexList[VertexCountOneSide * 2 - 1]);
}
void GenerateTriangleIndex()
{
//三角形索引
triangleList.Clear();
//上
int direction = -1;
int startIndex = 0;
for (int i = 0; i < NumberOfSides * 2; i++)
{
int[] triangleIndexs = getTriangleIndexs(i, direction);
direction *= -1;
for (int j = 0; j < triangleIndexs.Length; j++)
{
triangleList.Add(triangleIndexs[j]);
}
}
//下
direction = 1;
startIndex += (NumberOfSides + 1) * 2;
for (int i = 0; i < NumberOfSides * 2; i++)
{
int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex);
direction *= -1;
for (int j = 0; j < triangleIndexs.Length; j++)
{
triangleList.Add(triangleIndexs[j]);
}
}
//前
direction = 1;
startIndex += VertexCountOneSide;
for (int i = 0; i < NumberOfSides * 2; i++)
{
int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex);
direction *= -1;
for (int j = 0; j < triangleIndexs.Length; j++)
{
triangleList.Add(triangleIndexs[j]);
}
}
//后
direction = -1;
startIndex += VertexCountOneSide;
for (int i = 0; i < NumberOfSides * 2; i++)
{
int[] triangleIndexs = getTriangleIndexs(i, direction, startIndex);
direction *= -1;
for (int j = 0; j < triangleIndexs.Length; j++)
{
triangleList.Add(triangleIndexs[j]);
}
}
startIndex += VertexCountOneSide;
//左
triangleList.Add(startIndex + 0);
triangleList.Add(startIndex + 1);
triangleList.Add(startIndex + 2);
triangleList.Add(startIndex + 3);
triangleList.Add(startIndex + 2);
triangleList.Add(startIndex + 1);
//右
triangleList.Add(startIndex + 4 + 2);
triangleList.Add(startIndex + 4 + 1);
triangleList.Add(startIndex + 4 + 0);
triangleList.Add(startIndex + 4 + 1);
triangleList.Add(startIndex + 4 + 2);
triangleList.Add(startIndex + 4 + 3);
}
//UV索引
void GenerateUV()
{
uvList.Clear();
//上
for (int i = 0; i <= NumberOfSides; i++)
{
float angle = 180 - i * incrementAngle;
float littleX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(littleX, 0));
float bigX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(bigX, 1));
}
//下
for (int i = 0; i <= NumberOfSides; i++)
{
float angle = 180 - i * incrementAngle;
float littleX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(littleX, 0));
float bigX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(bigX, 1));
}
//前
for (int i = 0; i <= NumberOfSides; i++)
{
float angle = 180 - i * incrementAngle;
float littleX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(littleX, 0));
float bigX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(bigX, 1));
}
//后
for (int i = 0; i <= NumberOfSides; i++)
{
float angle = 180 - i * incrementAngle;
float littleX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(littleX, 0));
float bigX = (1.0f / NumberOfSides) * i;
uvList.Add(new Vector2(bigX, 1));
}
//左
uvList.Add(new Vector2(1.0f, 1.0f));
uvList.Add(new Vector2(0.0f, 1.0f));
uvList.Add(new Vector2(0.0f, 0.0f));
uvList.Add(new Vector2(1.0f, 0.0f));
//右
uvList.Add(new Vector2(1.0f, 1.0f));
uvList.Add(new Vector2(0.0f, 1.0f));
uvList.Add(new Vector2(0.0f, 0.0f));
uvList.Add(new Vector2(1.0f, 0.0f));
}
int[] getTriangleIndexs(int index, int direction, int startIndex = 0)
{
int[] triangleIndexs = new int[3] { 0+ startIndex, 1 + startIndex, 2 + startIndex };
for (int i = 0; i < triangleIndexs.Length; i++)
{
triangleIndexs[i] += index;
}
if (direction == -1)
{
int temp = triangleIndexs[0];
triangleIndexs[0] = triangleIndexs[2];
triangleIndexs[2] = temp;
}
return triangleIndexs;
}
private void Update()
{
GenerateMesh();
}
float[] GetCirclePoint(float radius, int index)
{
float angle = 180 - index * incrementAngle;
float[] points = new float[2];
float x = radius * Mathf.Cos(angle * Mathf.Deg2Rad);
float y = radius * Mathf.Sin(angle * Mathf.Deg2Rad);
points[0] = x;
points[1] = y;
return points;
}
float[] GetBezierPoint(int index)
{
float t = 1.0f / (NumberOfSides + 1) * index;
float[] points = new float[2];
var vec = Bezier(bezierPoints[0], bezierPoints[1], bezierPoints[2], bezierPoints[3], t);
points[0] = vec.x;
points[1] = vec.y;
return points;
}
Vector2 Bezier(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t)
{
Vector2 result;
Vector2 p0p1 = (1 - t) * p0 + t * p1;
Vector2 p1p2 = (1 - t) * p1 + t * p2;
Vector2 p2p3 = (1 - t) * p2 + t * p3;
Vector2 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
Vector2 p1p2p3 = (1 - t) * p1p2 + t * p2p3;
result = (1 - t) * p0p1p2 + t * p1p2p3;
return result;
}
}
Unity中用Mesh画一个圆环(二)的更多相关文章
- Unity中用Mesh画一个圆环
Probuider 前几天在做一个小项目的时候,用到了Unity自带的一个包ProBuilder其中的Arch生成1/4圆. 挺好玩的,可以在直接Unity中根据需要用Mesh定制生成图形,而不用建模 ...
- Unity3D UGUI Shader画一个圆环
Shader "Unlit/NewUnlitShader" { Properties { _MainTex ("Texture", 2D) = "wh ...
- Directx11学习笔记【十二】 画一个旋转的彩色立方体
上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧. 具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明. 由于我们要画彩色的立方体,所以顶点结构体 ...
- 如何用Photoshop画一个发光金币(unity游戏素材教程)
做好的发光金币预览图: 以下为如何用Photoshop画一个发光金币教程: [1]如上图1-2,新建,名称改为Coin,宽度20像素,高度20像素,分辨率72,背景白色: [2]使用Alt+Shift ...
- Java坦克大战 (二) 之画一个能动的圆圈代表坦克
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Unity中Mesh分解与边缘高亮加上深度检测
一个比较简单的需求,不过遇到些坑,记录下. 房间有多个模型,每个模型可能多个SubMesh,点击后,需要能具体到是那个SubMesh,并且在这个SubMesh上显示边缘高光,以及能个性这单个SubMe ...
- unity, editable mesh
一,需求 从fbx载入的模型是不可以在unity里编辑的. 我有一人特殊的需求就是想在unity里为mesh的各顶点K动画. 于是需要自己实现一个可编辑(其实只是顶点可以拖动)的mesh. 二,思路 ...
- iOS圆形图片裁剪,以及原型图片外面加一个圆环
废话不多说,直接上代码 #import "ViewController.h" @interface ViewController () @property (nonatomic,s ...
- 用PS画一个齿轮
以前只会画圆画方,这没技术含量.今天学了一个稍难一点的,画一个齿轮.图形有圆也有方.以下描述如何画出来的. 一.打开PS准备一画布,画一矩形并且填充颜色. 二.编辑->自由变换(CTRL+T), ...
随机推荐
- django安装以及配置
一.django的安装和启动 1.安装 pip3 install django==1.11.22 目前来讲1.11.22版本比较稳定 2.django的创建 命令行:cmd先去到django创建目录, ...
- Hadoop(MapR)分布式安装及自动化脚本配置
MapR的分布式集群安装过程还是很艰难的,远远没有计划中的简单.本人总结安装配置,由于集群有很多机器,手动每台配置是很累的,编写了一个自动化配置脚本,下面以脚本为主线叙述(脚本并不完善,后续继续完善中 ...
- Tree 点分治
题目描述 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K 输入输出格式 输入格式: N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是 ...
- 详细解读 Spring AOP 面向切面编程(一)
又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...
- Uipath 选择页面下拉列表中的选项
http://www.rpatokyo.com/ 使用Select item Activity选择页面下拉列表中的选项 在open browser中拖入Select Item Activity,配置参 ...
- xml 文件操作
'XML添加 Public Sub Add(ID As String, RFSerialnumber As String, Mood As Integer) If reatch(RFS ...
- maven 打包 spring boot 生成docker 镜像
1.所使用材料 ,spring boot 项目 基于maven ,maven 工具, docker工具 ps:为啥使用 docker 公司微服务需要启动太多,有两个优点吧! 1.方便管理,2.减少服务 ...
- Centos7 安装需要的软件环境
Mysql 安装 下载安装 下载并安装MySQL官方的 Yum Repository wget -i -c http://dev.mysql.com/get/mysql57-community-rel ...
- web开发资源导航
实用工具 前端在线工具 兼容性速查 html5兼容性查询 node-es6支持度 es6兼容性表查询 设备es6支持度 游览器H5支持度 浏览器内核检测工具 手机设备信息检测 浏览器市场份额 文档手册 ...
- Hadoop环境部署
1.虚拟机克隆 在VM界面点击查看-自定义-库,然后在左边我的计算机下右键点击安装好的第一个系统,然后管理-克隆,选择克隆系统所在的文件路径即可. 2.三台主机名字修改 root用户下: (1)编辑n ...