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

温州企业建站系统深圳住 建设局网站

温州企业建站系统,深圳住 建设局网站,网页设计模板素材旅游,wordpress upload 加密Unity即时战略/塔防项目实战#xff08;一#xff09;—— 构造网格建造系统 效果展示 Unity RTS游戏网格建造系统实现原理 地形和格子划分#xff0c;建造系统BuildManager构建 地形最终需要划分成一个一个的小方格#xff0c;首先定义一下小方格#xff1a; private…Unity即时战略/塔防项目实战一—— 构造网格建造系统 效果展示 Unity RTS游戏网格建造系统实现原理 地形和格子划分建造系统BuildManager构建 地形最终需要划分成一个一个的小方格首先定义一下小方格 private struct MapCellNode {public float height; // 格子的中心高度public float steepness; // 格子的梯度public Building current; // 格子中存储的建筑 }将地图分成m*n的小个子用一个二维数组容纳这些格子并对这些格子进行初始化 // 盛放格子的容器 private static MapCellNode[,] mapCells;// 初始化格子并计算每个格子的高度和坡度 private void InitMapCells() {var terrainData _terrain.terrainData;int gridWidth (int)(terrainData.bounds.size.x / cellSize.x);int gridHeight (int)(terrainData.bounds.size.z / cellSize.y);mapCells new MapCellNode[gridWidth, gridHeight];for (int i 0; i gridWidth; i){for (int j 0; j gridHeight; j){mapCells[i, j].current null;var center GetCellLocalPosition(i, j);mapCells[i, j].height center.y;var steepness terrainData.GetSteepness(center.x / terrainData.size.x, center.z/terrainData.size.z);mapCells[i, j].steepness steepness;}} }定义建造系统的一些API方便在其他地方使用 // 根据格子索引获取格子中心点的本地坐标 public static Vector3 GetCellLocalPosition(int w, int h) {Vector3 withoutHeight new(w * cellSize.x cellSize.x * 0.5f, 0, h * cellSize.y cellSize.y * 0.5f);return GetTerrainPosByLocal(withoutHeight); }// 根据格子索引获取格子中心点的世界坐标 public static Vector3 GetCellWorldPosition(int w, int h) {return Instance.transform.TransformPoint(GetCellLocalPosition(w, h)); }// 计算地图上的本地坐标点所属网格的索引 public static (int, int) GetCellIndexByLocalPosition(Vector3 local) {return ((int)(local.x / Instance._cellSize.x), (int)(local.z / Instance._cellSize.y)); }// 计算地图上的世界坐标点所属网格的索引 public static (int, int) GetCellIndexByWorldPosition(Vector3 world) {return GetCellIndexByLocalPosition(Instance.transform.InverseTransformPoint(world)); }// 根据给定的格子区域起始格子索引、宽度和高度计算区域内所有格子的平均高度 public static float GetGridAverageHeight(int sx, int sy, int w, int h) {float height 0;int count 0;for (int x sx; x sxw; x){if( x 0 || x gridSize.x)continue;for (int y sy; y sy h; y){if( y 0 || y gridSize.y)continue;height mapCells[x, y].height;count;}}if (count 0)return height / count;return 0; }PreBuilding 和“开始建造” 由于一次只能建造一个建筑因此当开始建造时首先持有待建造的物体用current来保存待建造的物体。 // 开始建造根据id查询待建物并持有它。 public static void TakeBuilding(string id) {if (!Instance.preBuildings.TryGetValue(id, out PreBuilding pb))return;BeginBuild(pb); }// 准备建造指定的建筑物 private static void BeginBuild(PreBuilding pb) {// 让待建物准备建造重置待建物的材质参数等pb.BeginBuild();currentBuilding pb;// 在待建物周围绘制方格线Instance.buildLineDrawer.gameObject.SetActive(true);Transform trans Instance.buildLineDrawer.transform;trans.SetParent(currentBuilding.transform);trans.localPosition projectorOffset - currentBuilding.AlignToCellOffset();// 如果待建物是具有攻击范围或影响范围的则显示范围指示器并设置半径为待建物的影响范围if (currentBuilding.canAttack){Instance.attackCircel.gameObject.SetActive(true);Instance.attackCircel.SetRadius(currentBuilding.AttackRadius);trans Instance.attackCircel.transform;trans.SetParent(currentBuilding.transform);trans.localPosition projectorOffset;} }然后就是建造检测逻辑 private void Update() {// 不在建造状态就返回if (currentBuilding is null || currentBuilding.IsBuilding){ #if DEBUG_MODDisplayDebugInfo(); #endifreturn;}// 按下右键就取消建造if (Input.GetMouseButtonDown(1)){CancelBuild();return;}// 不在UI上才建造if (EventSystem.current.IsPointerOverGameObject()){if (!Cursor.visible)Cursor.visible true;return;}// 获取建造点if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, 100f,groundLayer.value)){if (!Cursor.visible)Cursor.visible true;return;}if (Cursor.visible)Cursor.visible false;// 按下R键就旋转待建物换个朝向if (Input.GetKeyDown(KeyCode.R))currentBuilding.NextRotation();// 获取地图格子索引var (x, y) GetCellIndexByWorldPosition(hit.point);// 尝试放入待建物如无法放置返回falseif (currentBuilding.CheckBuildingIndexPosOnGrid(x, y)){// 按下左键准备结束建造if (Input.GetMouseButtonDown(0)){PrepareEndBuild();}} }检测能否放置在当前位置的方法如下 public bool CheckBuildingIndexPosOnGrid(int x, int y) {bool canBuild true;// 根据朝向计算当前占用格子的宽度和高度// 比如一个建筑物南北朝向放置时占用3*2个格子但是东西朝向放置时将占用2*3个格子。var (w, h) GetRealSizeWithDir();int dx (w - 1) / 2;int dy (h - 1) / 2;int sx x - dx;int sy y - dy;// 获取所占格子的平均地形高度float aheight BuildManager.GetGridAverageHeight(sx, sy, w, h);string info 超出范围;for (int px sx; canBuild px sx w; px){// 判定x方向是否超出地图边界if (px 0 || px BuildManager.gridSize.x){canBuild false;break;}for (int py sy; py sy h; py){// 判定z方向是否超出地图边界if (py 0 || py BuildManager.gridSize.y){canBuild false;break;}// 判定所占用的格子上是否已经存在其他建筑if (BuildManager.GetBuildingWithCell(px, py) is not null){canBuild false;info 已存在其他建筑;break;}// 判定格子地形高度与平均高度是否相差太多if (Mathf.Abs(aheight - BuildManager.GetCellHeight(px, py)) 0.2f){canBuild false;info 地形不平;break;}// 判定格子坡度是否太陡if (BuildManager.GetCellStepness(px, py) 3f){canBuild false;info 坡度太陡;break;}}}// 根据格子索引获取世界坐标并将其对齐到网格// AlignToCellOffset意义为假设待建物体的中心点在物体的几何中心那么如果所占格子尺寸为奇数// 则建筑是对称的偏移为0如果所占格子尺寸为偶数则该建筑不是对称的需要偏移半个单元格。var pos BuildManager.GetCellWorldPosition(x, y) AlignToCellOffset();// 如果能够在此处建造则设置索引并设置待建物材质为“绿色”否则设置为“红色”。if (canBuild){_indexPos.x sx;_indexPos.y sy;_indexPos.width w;_indexPos.height h;preMaterial.SetColor(CommDefine.PrebuildColor, BuildManager.preBuildNormalColor); }else{preMaterial.SetColor(CommDefine.PrebuildColor, BuildManager.preBuildBadColor);InfoTips.Display(info, pos, 1.2f );}// 设置待建物的世界坐标transform.position pos;return canBuild; }当按下鼠标确定在此处建造时 // 准备完成建造 private static void PrepareEndBuild() {// 恢复鼠标显示if (!Cursor.visible)Cursor.visible true;// 关闭网格显示、关闭范围指示开始播放建造动画currentBuilding.EndBuild();Instance.buildLineDrawer.gameObject.SetActive(false);if(currentBuilding.canAttack)Instance.attackCircel.gameObject.SetActive(false); }// 建造完成建造动画播放完成 private static void FinishBuild() {// 实例化真正要建造的物体Building bd currentBuilding.CreateBuilding();// 将建筑保存到网格中SaveCurrentBuilding(bd);// 置空currentcurrentBuilding null; }网格及范围指示的绘制 因为地形是不平的要在不平整的地面上完美的绘制网格和范围指示器那用到了投影贴花然后投影材质使用了自己写的shader很简单 网格的Shader fixed4 frag(const v2f i) : SV_Target {const float temp_output_2_0_g3 1 - _Width;const float2 appendResult10_g4 float2(temp_output_2_0_g3, temp_output_2_0_g3);const float2 temp_output_11_0_g4 abs(frac(i.uv0 * _ScaleOffset.xy _ScaleOffset.zw) * 2.0 -1.0) -appendResult10_g4;const float2 break16_g4 1.0 - temp_output_11_0_g4 / fwidth(temp_output_11_0_g4);float4 res 1 - saturate(min(break16_g4.x, break16_g4.y)).xxxx;const float len length(i.uv0 - float2(0.5,0.5));res * step(len, 0.5);res * smoothstep( 1-len, _min, _max);return res * _Color; }范围指示的Shader fixed4 frag(const v2f i) : SV_Target {const float radius _Radius * 0.5;const float width _Width * 0.5;const float len length(i.uv0 - float2(0.5,0.5));float4 res step(len, radius);const float4 inner step(len, radius - width);res - inner;res * _Color;return res; }建造过程动画 由于缺乏美术资源建造过程通过一个融合动画来展示建造过程融合用ASE插件做的Shader
http://www.w-s-a.com/news/289461/

相关文章:

  • 建设网站最强做网站哪一家公司好
  • 漫画风格网站人物介绍网页模板html
  • 贵阳市住房和城乡建设局政务网站大连 网站开发
  • 漳州市住房建设局网站网站一般多长
  • 国外做网站推广小程序制作二维码签到
  • 做网站需要域名网站建设诚信服务
  • 做物品租赁网站网站建设的完整流程
  • 响应式企业网站开发所用的平台西安知名网站推广
  • 高端响应式网站建设wordpress 全屏主题
  • 国内工程机械行业网站建设现状ui是什么意思
  • 成都网站开发哪家公司好出售家教网站模板
  • 订阅号做流量 那些电影如何链接网站温州市建设监理协会网站
  • 成都网站建设成功案例单招网商丘网站建设大全
  • 受欢迎的购物网站建设网推专员是做什么的
  • 商城网站前期准备湖南郴州建设局网站
  • 企业如何在自己的网站上做宣传外贸自建站可以自己做网站吗
  • 甘肃网站建设制作商网站空间哪家公司的好
  • 思途旅游网站建设系统用vscode做网站
  • 广州站改造最新消息半年工作总结ppt模板
  • logo模板下载网站推荐哪家网站开发培训好
  • 做外贸网站效果图页面关键词优化
  • 广平网站建设成都活动轨迹
  • 小型网站网站建设需要网络公司是什么行业
  • 滑动 手机网站 代码网页制作与设计讨论
  • 自己做网站处理图片用什么软件wordpress html5支持
  • 校园网站怎么建软文文案范文
  • 中国建设官方网站如何创建自己的软件
  • 来宾住房与城乡建设网站天津西青区怎么样
  • 西安网站建设培训班鄂州网页定制
  • 西部数码网站备份自己怎么做网站啊