Unity 网格建造

这篇具有很好参考价值的文章主要介绍了Unity 网格建造。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网格建造

游戏中常见的建造方式,目前在做的游戏中需要。

但搜出来的教程比较少,我又是个英文盲,没找到合适的方法,于是瞎研究了一个,说实话也挺简单的。

整体感觉还行,演示:

unity网格建造系统,个人开发,unity,游戏引擎

教程

变量

先定义几个变量

// 建筑的大小
public Vector2 buildSize;

// 建造区域起始点
public Vector2 startPoint;

// 可建造区域大小
public Vector2 buildArea;

// 建造指示器(变红变绿的那个东西,这个是左上角的那一个方块)
private GameObject buildObj;

// 当前建造指示器的位置
private Vector3 curPosition;

// 允许建造区域,外层字典是 X 内层是 Y
// 这里之前我用的是 Vector2 当作字典的 Key
// 但效率会不会有问题,不太懂,索性改成两层字典
private Dictionary<float, Dictionary<float, bool>> allowBuildArea = new Dictionary<float, Dictionary<float, bool>>();

// 是否允许建造
private bool allowBuild = false;

创建网格

首先根据 可建造区域大小 和 可建造区域起始点 创建网格,放到允许建造区域字典中

private void Start()
{
  // 构造网格
  for (int gridX = Mathf.CeilToInt(this.startPoint.x); gridX < this.startPoint.x + this.buildArea.x; gridX++)
  {

    for (int gridY = Mathf.CeilToInt(this.startPoint.y); gridY < this.startPoint.y + this.buildArea.y; gridY++)
    {
      // 没有内层字典则创建
      if (!this.allowBuildArea.ContainsKey(gridX))
      {
        this.allowBuildArea.Add(gridX, new Dictionary<float, bool>());
      }
      // 把坐标加进去
      this.allowBuildArea[gridX].Add(gridY, true);
    }

  }
}

建造指示器


然后是创建建造指示器,也就是红绿的方块,标识该坐标是否允许建造。

我这里是先创建一个放在左上角,其他会作为它的子级被创建。

private void CreateBuildIndicator()
{
  // 建筑大小指示的父级(左上角那个方块)
  this.buildObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
  this.buildObj.transform.localScale = new Vector3(1, 0.1f, 1);
  // 设置 layer,后面发射射线时会把 Build 这一层过滤掉
  this.buildObj.layer = LayerMask.NameToLayer("Build");
  buildGroup.Add(this.buildObj);
  // 这里是修改材质球可以设置透明度
  // 参考教程:https://www.cnblogs.com/chinarbolg/p/9601428.html
  SetTransparent(ScriptObjectPool<MeshRenderer>.Instance.GetComponent(this.buildObj).material);

  // 根据建筑大小 创建子级
  for (int buildX = 0; buildX < this.buildSize.x; buildX++)
  {

    for (int buildY = 0; buildY > -this.buildSize.y; buildY--)
    {
      // 0,0 位置是父级 所以不必创建
      if (buildX == 0 && buildY == 0) continue;

      // 创建子级 后面的设置基本跟父级一样
      GameObject buildChildren = GameObject.CreatePrimitive(PrimitiveType.Cube);
      buildChildren.transform.SetParent(this.buildObj.transform);
      buildChildren.transform.localScale = Vector3.one;
      buildChildren.transform.position = new Vector3(buildX, this.buildObj.transform.position.y, buildY);
      buildChildren.layer = LayerMask.NameToLayer("Build");
      SetTransparent(ScriptObjectPool<MeshRenderer>.Instance.GetComponent(buildChildren).material);

      buildGroup.Add(buildChildren);
    }
  }
}

发射射线


然后是发射射线,让建造指示器跟随鼠标

这一步可以直接在 Update() 里做,我这里是放到了一个循环计时器中

为了测试方便,我直接改成了右键创建建造指示器,左键建造

void Update()
{
  // 左键 && 允许建造
  if (Input.GetMouseButtonDown(0) && this.allowBuild)
  {
    Build();
  }
  // 右键
  if (Input.GetMouseButtonDown(1))
  {
    if (this.buildObj != null) return;
    // 创建建造指示器(就是上面那个方法)
    CreateBuildIndicator();
    // 开启循环计时器
    GameUtil.Instance.SetInterval((intervalID) =>
    {
      // 如果建筑指示器为空 则清除当前计时器
      if (this.buildObj == null)
      {
        GameUtil.Instance.RemoveInterval(intervalID);
        return;
      }
      // 鼠标位置的射线
      Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
      RaycastHit hit;
      // 发射射线,过滤掉 Build 层
      if (Physics.Raycast(ray, out hit, Mathf.Infinity, ~(1 << LayerMask.NameToLayer("Build"))))
      {
        // 让建造指示器的父级移动到鼠标左上角(让鼠标大致处于整个指示器中心)
        this.buildObj.transform.position = new Vector3(Mathf.Round(hit.point.x - this.buildSize.x / 2), hit.point.y + 0.1f, Mathf.Round(hit.point.z + this.buildSize.y / 2));
        // 如果上次保存的 当前位置 与 本次位置不相等 说明位置变了
        if (this.curPosition != this.buildObj.transform.position)
        {
          // 更新位置
          this.curPosition = this.buildObj.transform.position;
          // 调用位置改变的方法
          OnPositionChanged();
        }

      }

    }, 0.03f);

  }
}

// 当位置改变
private void OnPositionChanged()
{
  // 先允许建造
  this.allowBuild = true;

  // 循环建筑块
  foreach (var buildBlock in buildGroup)
  {
    Vector3 position = buildBlock.transform.position;
    // 判断当前格是否在可建造区域内 并且 该格是可建造的
    if (
      this.allowBuildArea.ContainsKey(position.x)
      && this.allowBuildArea[position.x].ContainsKey(position.z)
      && this.allowBuildArea[position.x][position.z] == true
    )
    {
      // 可建造 变成绿色
      // 这句代码等价于 buildBlock.GetComponent<MeshRenderer>().material......
      ScriptObjectPool<MeshRenderer>.Instance.GetComponent(buildBlock).material.color = new Color(0.1f, 1, 0.1f, 0.3f);
    }
    else
    {
      // 否则不允许建造
      this.allowBuild = false;
      // 变为红色
      ScriptObjectPool<MeshRenderer>.Instance.GetComponent(buildBlock).material.color = new Color(1, 0.1f, 0.1f, 0.3f);
    }
  }
}

左键执行的那个Build()就只是把当前的建造指示器改个颜色放在原位,实际游戏中会创建建筑,删掉建造指示器。

OK,以上就是这个网格建造的分享,告辞。文章来源地址https://www.toymoban.com/news/detail-535010.html

到了这里,关于Unity 网格建造的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity、UE、Cocos游戏开发引擎的区别

    Unity、Unreal Engine(UE)和Cocos引擎是三个常用的游戏开发引擎,它们在功能和特性上有一些区别。以下是它们之间的主要区别: 编程语言:Unity使用C#作为主要的编程语言,开发者可以使用C#脚本进行游戏逻辑编写。Unreal Engine主要使用C++作为编程语言,但也支持蓝图系统,允许

    2024年02月22日
    浏览(62)
  • 23. Unity - 3D游戏开发小计02 --- 动画结束UI、导航网格代理、场景搭建插件(ProGrids,ProBuilder,Polybrush)

    1. 动画结束UI 一个游戏在通过后,都是需要一个界面显示当前游戏已经结束,即需要给游戏添加一个结束的界面,可以做一个简单的游戏结束界面,用一个图片展示: 首先在 层级窗口 添加两层UI中的Image,其中第一层的Image仅作背景,可将其填充颜色设置为纯黑色,第二层的

    2024年02月05日
    浏览(52)
  • 【unity实战】手搓一个网格放置功能,及装修建造种植功能(2d3d通用,附源码)

    参考原视频链接 【视频】:https://www.youtube.com/watch?v=l0emsAHIBjU 注意 :本文为学习笔记记录,推荐支持原作者,去看原视频自己手敲代码理解更加深入

    2024年02月16日
    浏览(54)
  • Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

    一、简介 2. Unity相当于什么GameObject? 3. 如何设计一个由多种资产、生物等组成的关卡? 4. 在哪里放置特定角色的代码(例如生物、物品)?Unity 中“向 GameObject 添加 MonoBehaviour”相当于什么? 5.Unity子目录相当于什么Assets? 6. 支持哪些模型格式? 7. 支持FBX模型格式吗? 8.

    2024年02月07日
    浏览(76)
  • Unity引擎打包AssetBundle后模型网格数据丢失问题

    大家好,我是阿赵。 在项目里面,有时候会遇到这样一个问题。在Unity编辑器里面编写了一个shader,在编辑器看,效果都是没有问题的。但如果把资源打包成AssetBundle后,会发现shader的表现不对了。遇到了这种问题的时候,一般人会各自的怀疑,怀疑是不是shader写得不对,导

    2024年02月07日
    浏览(48)
  • 【用unity实现100个游戏之14】Unity2d做一个建造与防御类rts游戏(附项目源码)

    【视频】:https://www.udemy.com/course/awesome-builder-defender-game-in-unity/?couponCode=CMCOURSEDEC23 注意 :本文为学习笔记记录,推荐支持原作者,去看原视频自己手敲代码理解更加深入

    2024年02月05日
    浏览(55)
  • 吐槽laya:H5小游戏开发应该用什么引擎好?laya、cocos还是unity?

    我看有人推荐laya,放在H5小游戏的前三排名,这压根不靠谱。 laya只能算个半成品,整体非常垃圾,如果是首次选择游戏引擎,至少转去cocos,实在选laya,那也没办法了。 下面说说laya有什么问题,如果只是一些简单的bug什么的,我是不会花这个时间吐槽的,但是如下的问题实

    2024年02月13日
    浏览(60)
  • 游戏开发常用引擎工具介绍对比区别(UE4,Unity,Cocos,LayaAir,[egret-白鹭])

    是一套为开发实时技术而存在的引擎工具。目前广泛应用于3D建模渲染、游戏开发中。它完善的工具套件以及简易的工作流程能够使开发者快速修改或查看成果,对于代码的依赖性很低。而完整公开的源代码则能让使用者自由修改和扩展引擎功能。 是面向开发人员的 3D/2D 游戏

    2024年02月13日
    浏览(62)
  • Unity游戏开发之游戏动画(Unity动画系统)

    Unity动画系统分为 动画片段 Animation Clip: 动画资源,与模型无关 动画状态机 Animator Controller:帮助我们跟踪当前动画的播放状态,并且根据设置觉得如何切换动画片段 动画组件 Animator Component:玩家角色需要播放动画功能时,需要动画组件,将游戏对象需要的动画状态机(以

    2024年02月13日
    浏览(54)
  • C语言与游戏引擎插件开发:Unity、Unreal Engine中C插件的编写与集成(四)

    目录 一、C插件开发最佳实践与常见问题解析 性能优化: 跨平台兼容性: 版本管理与升级: 二、结论 C语言在游戏引擎插件开发中的关键作用与优势: 对开发者提出建议: 性能优化: 内存管理: 智能指针 :利用UE的 TSharedPtr 、 TWeakPtr 等智能指针管理动态内存,确保资源释

    2024年04月27日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包