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

可以做黄金期权的网站网页设计与制作课本

可以做黄金期权的网站,网页设计与制作课本,建设部网站注销一级建造师,十大旅游电子商务网站文章目录 最终效果前言绘制开始场景素材开始放置旋转物体扩展优化1. 绘制地图边界#xff0c;确保放置物品在指定区域内工作2. 让模型所占面积大小更加准确3. 隐藏白色瓦片指示区域 最终效果其他源码参考完结 最终效果 前言 其实3d物品建造装修系统之前就已经做过了#xff… 文章目录 最终效果前言绘制开始场景素材开始放置旋转物体扩展优化1. 绘制地图边界确保放置物品在指定区域内工作2. 让模型所占面积大小更加准确3. 隐藏白色瓦片指示区域 最终效果其他源码参考完结 最终效果 前言 其实3d物品建造装修系统之前就已经做过了感兴趣的可以去看看手搓一个网格放置功能及装修建造种植功能 但是它有一些缺点比如网格是自己绘制的使用起来可能比较麻烦所有这里分享另一种更加简单的方法。就是使用tilemap可以省略自己绘制复杂网格的时间但是缺点可能就是玩家无法在游戏界面看到网格的具体位置当然实现功能千千万万选择自己喜欢的就行。 绘制开始场景 在平台上放置tilemap并配置对应参数 简单绘制效果 素材 可以寻找下载你喜欢的模型导入到项目中 这里我推荐个地址 https://sketchfab.com/Cytiene/collections/great-downloadable-models-6304c532e52649f59de0de234edcb91f 开始 新增可放置对象脚本PlaceableObject 暂时什么都不做 public class PlaceableObject : MonoBehaviour { }所有模型物品都挂载脚本并给模型添加碰撞体 新增BuildingSystem定义一个建筑系统的脚本 public class BuildingSystem : MonoBehaviour {public static BuildingSystem current;public GridLayout gridLayout;private Grid grid;[SerializeField] private Tilemap mainTilemap; // 地图的Tilemap组件[SerializeField] private TileBase whiteTile; // 白色方块的TileBasepublic GameObject prefab1; // 预制体1public GameObject prefab2; // 预制体2private PlaceableObject objectToPlace; // 当前要放置的对象private void Awake(){current this;grid gridLayout.gameObject.GetComponentGrid(); // 获取网格组件}//测试切换不同模型物品private void Update(){if (Input.GetKeyDown(KeyCode.A)){InitializeWithObject(prefab1);}else if (Input.GetKeyDown(KeyCode.B)){InitializeWithObject(prefab2);}}// 工具方法将鼠标位置转换为世界坐标系下的位置public static Vector3 GetMouseWorldPosition(){// 从相机发出一条射线将鼠标位置转换为世界坐标系下的位置Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);// 如果射线碰撞到物体则返回碰撞点的世界坐标if (Physics.Raycast(ray, out RaycastHit raycastHit)){return raycastHit.point;}else // 否则返回零向量{return Vector3.zero;}}// 将坐标对齐到网格上public Vector3 SnapCoordinateToGrid(Vector3 position){Vector3Int cellPos gridLayout.WorldToCell(position); // 将世界坐标转换为网格单元坐标position grid.GetCellCenterWorld(cellPos); // 获取网格单元中心点的世界坐标return position;}//初始化放置物体public void InitializeWithObject(GameObject prefab){// 将物体初始位置设为网格对齐的原点Vector3 position SnapCoordinateToGrid(Vector3.zero);// 在初始位置实例化物体GameObject obj Instantiate(prefab, position, Quaternion.identity);// 获取PlaceableObject组件并添加ObjectDrag组件objectToPlace obj.GetComponentPlaceableObject(); // 获取可放置物体组件obj.AddComponentObjectDrag(); // 添加拖拽组件} }新增ObjectDrag定义一个物体拖拽的脚本注意物品移动要有碰撞体不然拖拽不会生效 public class ObjectDrag : MonoBehaviour {private Vector3 offset; // 鼠标按下时物体和鼠标之间的偏移量// 当鼠标按下时记录偏移量private void OnMouseDown(){offset transform.position - BuildingSystem.GetMouseWorldPosition();}// 当鼠标拖动时移动物体并对齐到网格上private void OnMouseDrag(){Vector3 pos BuildingSystem.GetMouseWorldPosition() offset;transform.position BuildingSystem.current.SnapCoordinateToGrid(pos);} }挂载脚本配置 效果按AB生成不同的物品点击物品可以进行拖拽 当然你也可以修改ObjectDrag直接使用Update方法让物品一直跟随鼠标移动 // 每帧更新建筑物的位置 private void Update() {Vector3 pos BuildingSystem.GetMouseWorldPosition() offset;transform.position BuildingSystem.current.SnapCoordinateToGrid(pos); }放置 修改PlaceableObject public class PlaceableObject : MonoBehaviour {// 是否已经放置public bool Placed { get; private set; }// 物体占据的格子数public Vector3Int Size { get; private set; }// 物体碰撞器的四个顶点本地坐标系private Vector3[] Vertices;private void Start(){// 获取物体碰撞器的四个顶点GetColliderVertexPositionsLocal();// 计算物体占据的格子数CalculateSizeInCells();}// 获取物体碰撞器的四个顶点private void GetColliderVertexPositionsLocal(){BoxCollider b gameObject.GetComponentBoxCollider();Vertices new Vector3[4];Vertices[0] b.center new Vector3(-b.size.x, -b.size.y, -b.size.z) * 0.5f;Vertices[1] b.center new Vector3(b.size.x, -b.size.y, -b.size.z) * 0.5f;Vertices[2] b.center new Vector3(b.size.x, -b.size.y, b.size.z) * 0.5f;Vertices[3] b.center new Vector3(-b.size.x, -b.size.y, b.size.z) * 0.5f;}// 计算物体占据的格子数private void CalculateSizeInCells(){Vector3Int[] vertices new Vector3Int[Vertices.Length];for (int i 0; i vertices.Length; i){// 将物体顶点从本地坐标系转换到世界坐标系Vector3 worldPos transform.TransformPoint(Vertices[i]);// 将世界坐标系中的位置转换成格子坐标系中的位置vertices[i] BuildingSystem.current.gridLayout.WorldToCell(worldPos);}// 计算物体占据的格子数Size new Vector3Int(Mathf.Abs(vertices[0].x - vertices[1].x),Mathf.Abs(vertices[0].y - vertices[3].y),1);}// 获取物体的起始位置左下角的格子位置public Vector3 GetStartPosition(){return transform.TransformPoint(Vertices[0]);}// 放置物体public virtual void Place(){// 删除物体拖拽组件ObjectDrag drag gameObject.GetComponentObjectDrag();Destroy(drag);// 标记物体已经放置Placed true;// TODO触发放置事件} }修改BuildingSystem private void Update() {//。。。//放置测试if (Input.GetKeyDown(KeyCode.Space)){if (CanBePlaced(objectToPlace)) // 检查物体是否可以放置{objectToPlace.Place(); // 放置物体Vector3Int start gridLayout.WorldToCell(objectToPlace.GetStartPosition()); // 将世界坐标转换为格子坐标TakeArea(start, objectToPlace.Size); // 将物体所占据的区域填充为白色瓦片}else{Destroy(objectToPlace.gameObject); // 物体无法放置销毁物体}}else if (Input.GetKeyDown(KeyCode.Escape)){Destroy(objectToPlace.gameObject); // 按下 Esc 键销毁物体} }//获取一个区域内的瓦片信息数组 private static TileBase[] GetTilesBlock(BoundsInt area, Tilemap tilemap) {TileBase[] array new TileBase[area.size.x * area.size.y * area.size.z];int counter 0;foreach (var v in area.allPositionsWithin){Vector3Int pos new Vector3Int(v.x, v.y, 0);array[counter] tilemap.GetTile(pos); // 获取指定位置上的瓦片counter;}return array; }//检查物体是否可以放置在指定位置 private bool CanBePlaced(PlaceableObject placeableObject) {BoundsInt area new BoundsInt();area.position gridLayout.WorldToCell(placeableObject.GetStartPosition()); // 将世界坐标转换为格子坐标area.size placeableObject.Size; // 获取物体所占据的格子大小TileBase[] baseArray GetTilesBlock(area, mainTilemap); // 获取该区域内的瓦片数组foreach (var b in baseArray){if (b whiteTile) // 如果有白色瓦片表示物体无法放置{return false;}}return true; // 没有白色瓦片可以放置物体 }//在指定区域填充为白色瓦片 public void TakeArea(Vector3Int start, Vector3Int size) {mainTilemap.BoxFill(start, whiteTile, start.x, start.y, start.x size.x, start.y size.y); // 将指定区域填充为白色瓦片 }效果物体重叠会直接销毁物品 旋转物体 修改PlaceableObject //旋转 public void Rotate() {transform.Rotate(eulers: new Vector3(0, 90, 0)); // 绕 Y 轴顺时针旋转 90 度// 交换长宽并限制高度为 1Size new Vector3Int(Size.y, Size.x, 1);// 旋转顶点数组Vector3[] vertices new Vector3[Vertices.Length];for (int i 0; i vertices.Length; i){vertices[i] Vertices[(i 1) % Vertices.Length]; // 将顶点数组顺时针旋转}Vertices vertices; // 更新顶点数组 }修改BuildingSystem调用 private void Update() { //。。。//按回车旋转物体if (Input.GetKeyDown(KeyCode.Return)){objectToPlace.Rotate();} }效果 扩展优化 1. 绘制地图边界确保放置物品在指定区域内工作 在建筑区域周围绘制瓷砖边框这将增加图块地图边界效果并确保放置物品在指定区域内工作。 2. 让模型所占面积大小更加准确 现在TileMap每格网格比较大为了让模型所占面积大小更加准确可以适当缩小Grid的比例 效果 3. 隐藏白色瓦片指示区域 实际使用我们肯定不想看到白色瓦片所显示的指示区域我们可以关闭Tilemap Renderer或者修改TileMap颜色透明的为0 效果 最终效果 其他 后续其他内容我就不继续完善了留给大家自己去发挥比如 添加一些放置特效、动画、音效删除功能无法放置显示红色未放置显示蓝色显示可放置物品UI切换物品等等。。。 源码 源码整理好了我会放上来催更加急 参考 【视频】https://www.youtube.com/watch?vrKp9fWvmIwwt567s 完结 赠人玫瑰手有余香如果文章内容对你有所帮助请不要吝啬你的点赞评论和关注以便我第一时间收到反馈你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法也欢迎评论私信告诉我哦 好了我是向宇https://xiangyu.blog.csdn.net 一位在小公司默默奋斗的开发者出于兴趣爱好于是最近才开始自习unity。如果你遇到任何问题也欢迎你评论私信找我 虽然有些问题我可能也不一定会但是我会查阅各方资料争取给出最好的建议希望可以帮助更多想学编程的人共勉~
http://www.dnsts.com.cn/news/48952.html

相关文章:

  • 网站404网页界面psd源文件模板浩森宇特北京做网站
  • 做西餐的网站做美食推广的网站有哪些
  • 让网站降权商城软件开发多少钱
  • 人才网站建设经费用途WordPress要学多久
  • 酒店门户网站建设背景驻马店市住房和城乡建设局网站首页
  • 建站优化全包手机上网站
  • 酒业为什么做网站网站怎么做才美观
  • 那里有网站建设做网站定制开发的公司
  • 太仓网站建设教程书香校园网站建设
  • 网站建设完毕后怎么加后台wordpress托管是什么
  • 安溪哪里有学做网站长沙建设企业网站
  • 爱企业在线查询太极seo
  • wordpress 建购物网站电商网站建设需求分析 实例题
  • 门户网站开发要多久一单一结手机兼职
  • 建设部施工安全管理网站wordpress 多站点 多域名
  • 做网站用花生壳哪个版本免费招收手游代理内服号
  • 太原网站建设价格套餐算命先生的网站怎么做
  • 如何制作自己的网站视频教程做网站免费搭建
  • 国外做meta分析的网站邢台seo排名
  • 芜湖做网站优化wordpress怎么弄
  • 住房建设部投诉网站无锡做公司网站
  • 饲料行业怎么做网站sem账户托管公司
  • 山东网站建设网站推广公司网站模板怎么做
  • app网站如何做推广爱用建站怎么样
  • 网站模板免费下载中文版湖北省建设厅网站上岗证查询
  • 建站公司佛山手机网站 域名解析
  • 网站 运营南宁网站开发价格
  • 综合网站有哪些wordpress首页设置描述在什么位置
  • 做家居网站设计常用的设计网站
  • 哪些网站页面简洁淄博网站备案