当前位置: 首页 > news >正文

网站备案年限昆明网站建设搜q479185700

网站备案年限,昆明网站建设搜q479185700,重庆大型网络公司,沧州建网站现在steam上面有很多下棋类/经营类的游戏都是用六边形的地形#xff0c;比较美观而且实用#xff0c;去年在版本末期我也自己尝试做了一个绘制六边体的demo#xff0c;一年没接触unity竟然都要忘光了#xff0c;赶紧在这边记录一下。 想cv代码可以直接拉到代码章节 功能 …现在steam上面有很多下棋类/经营类的游戏都是用六边形的地形比较美观而且实用去年在版本末期我也自己尝试做了一个绘制六边体的demo一年没接触unity竟然都要忘光了赶紧在这边记录一下。 想cv代码可以直接拉到代码章节 功能 能够动态生成一系列可以“挖空中心”的六边形。指定innerWidth为0也可以生成实心的六边体。 能够生成平铺/直铺的六边形群调整之间距离 绘制思路 将绘制一个六边形看成六个下面这种等腰体绕中心旋转60度之后合并成一个。 一个这种等腰体又可以看成绘制四个面上面的等腰梯形内测的长方形下面的等腰梯形外侧的长方形两边无需绘制因为合并之后不会显示出来。 所以只需要通过三角函数计算出我们所需的所有点-拼出一个面-合成一个等腰体-合成一个六边体。 组件 我们需要一个MeshFilter来设置mesh一个MeshRenderer来设置mesh的材质。同时需要对mesh所需的内置成员变量有些了解。 m_meshFilter GetComponentMeshFilter();m_meshRenderer GetComponentMeshRenderer();m_mesh new Mesh();m_mesh.name HexMesh;m_meshFilter.mesh m_mesh;m_meshRenderer.material m_material;//最终数据传入m_mesh.vertices verticles.ToArray();m_mesh.triangles tris.ToArray();m_mesh.uv uvs.ToArray();m_mesh.RecalculateNormals();具体计算 绘制某个点 根据前面需要绘制的等腰梯形设A是梯形长边的点B是梯形短边的点易得平面内某个点的计算方式 定义一个CreatePoint接口根据width和y轴高度height来生成某个点的三维向量注意unity下生成图中y轴实际上是三维空间的z轴 private Vector3 CreatePoint(float distance, float height, float angle){float rad angle * Mathf.Deg2Rad; //Mathf接收的参数需要是弧度制return new Vector3(distance * Mathf.Cos(rad), height, distance * Mathf.Sin(rad));}生成面所需的数据 上文提到的等腰体四个不同面实际上都是四个顶点组成的并且都是两个点组成的平行的线段所以我们可以提供一个接口只需指定高度和半径就可以画出这四种不同的面同时存在上下和内外两侧面的朝向是相反的所以提供reverse接口来进行反向。 /// summary/// 上下底面的单独一个等腰梯形/// /summary/// param nameinnerRad内径/param/// param nameouterRad外径/param/// param nameheightA外高/param/// param nameheightB内高/param/// param namepoint顺序/param/// param namereverse连接方向/param/// returns/returnsprivate Face CreateFace(float innerRad, float outerRad, float heightA, float heightB, int point, bool reverse false){float angle1 point * 60;float angle2 angle1 60;if (!isFlat){ //竖着排布初始角度是-30angle1 - 30;angle2 - 30;}ListVector3 verticals new ListVector3();//.......C.//..B.......//..........//...A......Dverticals.Add(CreatePoint(innerRad, heightA, angle1));verticals.Add(CreatePoint(innerRad, heightA, angle2));verticals.Add(CreatePoint(outerRad, heightB, angle2));verticals.Add(CreatePoint(outerRad, heightB, angle1));Listint tris new Listint { 0, 1, 2, 2, 3, 0};ListVector2 uv new ListVector2 { new Vector2(0, 0),new Vector2(1,0),new Vector2(1,1),new Vector2(0,1) };//vertical顺序颠倒就会按照顺时针绘制。if(reverse){verticals.Reverse();}return new Face(verticals, tris, uv);}这里有一些关于mesh的基础知识首先是三个顶点能够组成一个面从上往下看如果点之间是逆时针顺序的话就是面向我们的。这里我们添加了四个点。tirs指定其顺序每三个一组将会连成一个面uvs代表是渲染的时候的uv坐标这里如果六边体有规范的话就需要根据需求设置对应的uv值这里就不关注这个了。 Listint tris new Listint { 0, 1, 2, 2, 3, 0};ListVector2 uv new ListVector2 { new Vector2(0, 0),new Vector2(1,0),new Vector2(1,1),new Vector2(0,1) };public struct Face {//顶点位置数组public ListVector3 verticles { get; private set; }//三角形顶点索引数组按给定的顺序连接顶点为顺时针三个一组的顺序public Listint triangles { get; private set; }public ListVector2 uvs { get; private set; }public Face(ListVector3 verticles, Listint triangles, ListVector2 uvs){this.verticles verticles;this.triangles triangles;this.uvs uvs;} }这样能够生产出一个面接下来我们批量生产所需的面,只需要不断让角度偏移60度忘记了可以去看上面计算A点坐标重复刚才的步骤将所有的面的数据都生成 private void DrawFaces(){m_faces new ListFace();//上表面for(int point 0; point 6; point ){m_faces.Add(CreateFace(innerWidth, outerWidth, height / 2, height / 2, point));}//下表面for (int point 0; point 6; point){m_faces.Add(CreateFace(innerWidth, outerWidth,- height / 2, -height / 2, point,true));}//侧面for (int point 0; point 6; point){m_faces.Add(CreateFace(outerWidth, outerWidth, height / 2, -height / 2, point));}//里侧面for (int point 0; point 6; point){m_faces.Add(CreateFace(innerWidth, innerWidth, height / 2, -height / 2, point,true));}}组装 刚才我们将数据填入Face但是Face是不能直接使用的我们要将刚才生成的顶点信息uv信息三角形信息等一次灌入Mesh中, Mesh提供了成员变量来接收这些数据。 顶点和uv直接添加就可以注意三角形数据需要根据顶点数据来加下标。 private void CombineFaces(){ListVector3 verticles new ListVector3();Listint tris new Listint();ListVector2 uvs new ListVector2();for(int i 0; i m_faces.Count; i){verticles.AddRange(m_faces[i].verticles); //AddRange方法可以把list中所有数据从头到尾添加到新的listuvs.AddRange(m_faces[i].uvs);//注意这里需要依次指定指定所有顶点在最终mesh的三角形顺序由于每个face里面包括四个顶点每次4int offset (4 * i);foreach(int triangle in m_faces[i].triangles){tris.Add(triangle offset);}}m_mesh.vertices verticles.ToArray();m_mesh.triangles tris.ToArray();m_mesh.uv uvs.ToArray();m_mesh.RecalculateNormals();}排布 要让游戏能玩肯定需要一系列整齐布局的六边形所以我们需要一个动态创建六边形的管理器。 横向布局 前面我们生成面的时候发现有个isFlat变量这个变量就是控制了第一个面的生成角度,所以横向的时候能保证六边形是横着的。 private Face CreateFace(float innerRad, float outerRad, float heightA, float heightB, int point, bool reverse false){float angle1 point * 60;float angle2 angle1 60;if (!isFlat){ //竖着排布初始角度是-30angle1 - 30;angle2 - 30;}......问题是如何计算出每个六边形的中心点在哪。这里用三角函数也非常容易看出来 下面是六边体“直立“”情况下设两个六边形之间间隔为d六边形中心到外顶点的距离为L 可以发现Y轴方向每个六边形之间距离为L * cos(30°) * 2 d* sin60° X轴方向每个六边形之间距离为(L*(cos(30°)*2 d) 同时注意距离偶数行的X轴要添加一个L * cos(30°) * 2 d*sin30°的偏移 具体计算就初中级别的数学就不一步步画图了 同理横向布局也很好计算 可以发现Y轴方向每个六边形之间距离为L * cos(30°) * 2 d X轴方向每个六边形之间距离为(L*(cos(30°)*2 d) *sin60° 同时注意距离偶数行的Y轴要添加一个L * cos(30°) * 2 d*sin30°的偏移 万事具备我们只需要计算每一行每列的点即可生成蜂窝了。 public void SetInterval(){centerDistance outterWidth * 2 * Mathf.Sin(60 * Mathf.Deg2Rad) interval;}private void UpdateGrid(GameObject[][] girds){if (girds.Length 0) return;bool shouldOffset false;for (int j 0; j heightCount; j){if (!isFlat){shouldOffset j % 2 ! 0;}for (int i 0; i widthCount; i){if (isFlat){shouldOffset i % 2 ! 0;}HexagonRenderer render girds[i][j].GetComponentHexagonRenderer();//计算六边形位置Vector3 pos Getpos(i, j, shouldOffset);Debug.Log(pos);render.SetAtrributes(innerWidth, outterWidth, height, pos, matrial, isFlat);render.DrawMesh();}}}private Vector3 Getpos(int i, int j, bool shouldOffset){float angle60 60 * Mathf.Deg2Rad;float angle30 30 * Mathf.Deg2Rad;if (isFlat){if (shouldOffset){return new Vector3(i * centerDistance * Mathf.Sin(angle60) , transform.position.y, j * centerDistance centerDistance * Mathf.Sin(angle30));}else{return new Vector3(i * centerDistance * Mathf.Sin(angle60), transform.position.y, j * centerDistance);}}else{if (shouldOffset){return new Vector3(i * centerDistance centerDistance * Mathf.Sin(angle30), transform.position.y, j * centerDistance * Mathf.Sin(angle60));}else{return new Vector3(i * centerDistance, transform.position.y, j * centerDistance * Mathf.Sin(angle60));}}}完整代码 在场景中创建一个空物体将GenerateMap.cs挂载在其身上即可,将会自动生成一系列身上挂载HexagonRenderer.cs的物体 GenerateMap.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class GenerateMap : MonoBehaviour {[Header(Grid Settings)]public int widthCount;public int heightCount;[Header(Layout Settings)]public float innerWidth;public float outterWidth;public float height;public bool isFlat;public Material matrial;/// summary/// 六边形之间的间隔/// /summarypublic float interval;private float centerDistance;/// summary/// 存储所有的六边形/// /summaryprivate GameObject[][] girds;private bool hasGenerate false;public void Start(){girds new GameObject[widthCount][];for (int i 0; i girds.Length; i){girds[i] new GameObject[heightCount];}SetInterval();GenerateGrid();LayoutGrid();}public void SetInterval(){centerDistance outterWidth * 2 * Mathf.Sin(60 * Mathf.Deg2Rad) interval;}/// summary/// 设置六边形布局从左下角生成/// /summaryprivate void LayoutGrid(){UpdateGrid(girds);}private void GenerateGrid(){if (hasGenerate true) return;for (int j 0; j heightCount; j){for (int i 0; i widthCount; i){GameObject single new GameObject($HEX:({i},{j}), typeof(HexagonRenderer)); //$代表string.formatgirds[i][j] single;single.transform.SetParent(transform, true);}}hasGenerate true;}private void UpdateGrid(GameObject[][] girds){if (girds.Length 0) return;bool shouldOffset false;for (int j 0; j heightCount; j){if (!isFlat){shouldOffset j % 2 ! 0;}for (int i 0; i widthCount; i){if (isFlat){shouldOffset i % 2 ! 0;}HexagonRenderer render girds[i][j].GetComponentHexagonRenderer();//计算六边形位置Vector3 pos Getpos(i, j, shouldOffset);Debug.Log(pos);render.SetAtrributes(innerWidth, outterWidth, height, pos, matrial, isFlat);render.DrawMesh();}}}private Vector3 Getpos(int i, int j, bool shouldOffset){float angle60 60 * Mathf.Deg2Rad;float angle30 30 * Mathf.Deg2Rad;if (isFlat){if (shouldOffset){return new Vector3(i * centerDistance * Mathf.Sin(angle60) , transform.position.y, j * centerDistance centerDistance * Mathf.Sin(angle30));}else{return new Vector3(i * centerDistance * Mathf.Sin(angle60), transform.position.y, j * centerDistance);}}else{if (shouldOffset){return new Vector3(i * centerDistance centerDistance * Mathf.Sin(angle30), transform.position.y, j * centerDistance * Mathf.Sin(angle60));}else{return new Vector3(i * centerDistance, transform.position.y, j * centerDistance * Mathf.Sin(angle60));}}} } HexagonRenderer.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public struct Face {//顶点位置数组public ListVector3 verticles { get; private set; }//三角形顶点索引数组按给定的顺序连接顶点为顺时针三个一组的顺序public Listint triangles { get; private set; }public ListVector2 uvs { get; private set; }public Face(ListVector3 verticles, Listint triangles, ListVector2 uvs){this.verticles verticles;this.triangles triangles;this.uvs uvs;} } [RequireComponent(typeof(MeshFilter))] [RequireComponent(typeof(MeshRenderer))]public class HexagonRenderer : MonoBehaviour {private Mesh m_mesh;private MeshFilter m_meshFilter;private MeshRenderer m_meshRenderer;private ListFace m_faces;private bool isFlat true;public Material m_material;public float innerWidth;public float outerWidth;public float height;private void Awake(){m_meshFilter GetComponentMeshFilter();m_meshRenderer GetComponentMeshRenderer();m_mesh new Mesh();m_mesh.name HexMesh;m_meshFilter.mesh m_mesh;m_meshRenderer.material m_material;}public void SetAtrributes(float innerWidth, float outerWidth, float height, Vector3 position, Material material, bool isFlat){this.innerWidth innerWidth;this.outerWidth outerWidth;this.isFlat isFlat;this.height height;transform.position position;m_material material;m_meshRenderer.material m_material;DrawMesh();}private void OnEnable(){DrawMesh();}//渲染整个六边形体public void DrawMesh(){DrawFaces();CombineFaces();}private void OnValidate(){}private void DrawFaces(){m_faces new ListFace();//上表面for (int point 0; point 6; point){m_faces.Add(CreateFace(innerWidth, outerWidth, height / 2, height / 2, point));}//下表面for (int point 0; point 6; point){m_faces.Add(CreateFace(innerWidth, outerWidth, -height / 2, -height / 2, point, true));}//侧面for (int point 0; point 6; point){m_faces.Add(CreateFace(outerWidth, outerWidth, height / 2, -height / 2, point));}//里侧面for (int point 0; point 6; point){m_faces.Add(CreateFace(innerWidth, innerWidth, height / 2, -height / 2, point, true));}}private void CombineFaces(){ListVector3 verticles new ListVector3();Listint tris new Listint();ListVector2 uvs new ListVector2();for (int i 0; i m_faces.Count; i){verticles.AddRange(m_faces[i].verticles);AddRange方法可以把list中所有数据从头到尾添加到新的listuvs.AddRange(m_faces[i].uvs);//注意这里需要依次指定指定所有顶点在最终mesh的三角形顺序由于每个face里面包括四个顶点每次4int offset (4 * i);foreach (int triangle in m_faces[i].triangles){tris.Add(triangle offset);}}m_mesh.vertices verticles.ToArray();m_mesh.triangles tris.ToArray();m_mesh.uv uvs.ToArray();m_mesh.RecalculateNormals();}/// summary/// 上下底面的单独一个等腰梯形/// /summary/// param nameinnerRad内径/param/// param nameouterRad外径/param/// param nameheightA外高/param/// param nameheightB内高/param/// param namepoint顺序/param/// param namereverse连接方向/param/// returns/returnsprivate Face CreateFace(float innerRad, float outerRad, float heightA, float heightB, int point, bool reverse false){float angle1 point * 60;float angle2 angle1 60;if (!isFlat){angle1 - 30;angle2 - 30;}ListVector3 verticals new ListVector3();//.......C.//..B.......//..........//...A......Dverticals.Add(CreatePoint(innerRad, heightA, angle1));verticals.Add(CreatePoint(innerRad, heightA, angle2));verticals.Add(CreatePoint(outerRad, heightB, angle2));verticals.Add(CreatePoint(outerRad, heightB, angle1));Listint tris new Listint { 0, 1, 2, 2, 3, 0 };ListVector2 uv new ListVector2 { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) };if (reverse){verticals.Reverse();}return new Face(verticals, tris, uv);}/// summary/// 创造一个顶点/// /summary/// param namedistance距离坐标原点距离/param/// param nameheighty轴高度/param/// param nameangle和坐标轴所成夹角/param/// returns/returnsprivate Vector3 CreatePoint(float distance, float height, float angle){float rad angle * Mathf.Deg2Rad;return new Vector3(distance * Mathf.Cos(rad), height, distance * Mathf.Sin(rad));} }
http://www.zqtcl.cn/news/846507/

相关文章:

  • 学校网站源码小游戏网站审核怎么做
  • 西乡网站建设政务网站开发协议
  • 美食网站开发环境北京app网站建设
  • 郑州网站建设推广渠道重庆网站建设公司下载
  • 宜宾营销型网站建设网站建设需要什么资质
  • 重庆建网站有哪些学跨境电商要多少钱
  • 上海建设钢结构工程网站深圳电器公司排名
  • 淄博网站建设找淄深网江苏省建设斤网站
  • 免费行情软件app网站红色西安做网站印象网络
  • 宁波网站建设小程序开发聊城wap网站建设
  • 陇南网站网站建设泰安网站的建设
  • 哪个网站有介绍拿到家做的手工活建设银行网站怎么修改手机号码吗
  • 网站地图怎么用淘宝客推广网站建设
  • 外贸零售网站建设购物网站支付功能怎么做
  • 淘宝客如何做自己的网站西宁工程建设招聘信息网站
  • 天津都有哪些制作网站郑州官网首页
  • 个人网站开发模式海南省建设公司官网
  • edu网站开发做爰视频在线观看免费网站
  • 安防公司网站模板网站建设模板下载
  • 贵阳网站建设方案维护一 建设茶叶网站前的市场分析
  • 山东东营建设网官方网站百度电脑版
  • 做网站前途如何海尔网站建设推广
  • 投资公司网站建设万网域名安装wordpress
  • 高端网站建设企业官网建设wordpress相似推荐
  • php网站开发师招聘wordpress怎么换头像
  • 门禁考勤网站建设广西建设
  • 互助盘网站怎么做的织梦免费企业网站
  • 做羊毛毡的网站电子商务网站建设品牌
  • 用vue做商城网站常用的js教做发型的网站
  • 江西省寻乌县建设局网站广州网站建设一般多少钱