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

Unreal 实现建造游戏|地面交互shader

在方形模块中,通过创建两个shader来实现建造游戏的地面shader效果:

  • 整个地图分为n个方形grid,使用材质的“世界坐标”来区分模块。
  • 创建一个可建造区域的shader,当玩家建造后,创建一个不可建造区域的shader,使用另一个shader将已建造区域的材质更改为不可建造状态,可以是一个灰色或不同纹理的材质。

通过将世界坐标转换为网格坐标,确定模块在网格中的位置。你可以用简单的数学运算(例如取整)来实现这一点。可以使用 Floor 节点:(HLSL)

GridX = floor(WorldPosition.x / GridSize);
GridY = floor(WorldPosition.y / GridSize);

可以通过纹理将模块状态传递到材质中。将可建造和不可建造模块的状态存储在一张纹理上,然后在材质中采样这张纹理。

利用“自定义节点”来进行条件判断,基于是否已有模块来切换材质。这样就能很直观地显示可建造和不可建造的区域。

1.选择你的基础材质,打开材质编辑器。

2.在材质图中右键单击,选择“添加节点” > “自定义”节点。

3.在“自定义”节点的输入端口连接你的条件逻辑。你可以根据模块的状态(例如一个布尔值)来判断:

输出:根据这个布尔值选择材质。

输入:一个布尔值(例如 IsBuildable),表示是否可以建造。

条件逻辑(HLSL):

return IsBuildable ? BuildableColor : NotBuildableColor;

以上是用蓝图实现,用cpp如下

UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this);
DynamicMaterial->SetScalarParameterValue("IsBuildable", (canBuild ? 1.0f : 0.0f));
YourMeshComponent->SetMaterial(0, DynamicMaterial);

 

2.继续建造的时候要保证你选的grid(如一次覆盖300*300)没有任何一个角落和不可建造的模块重合。

实现这个功能的思路可以分为几个步骤:

  1. 区域检测

    • 创建一个函数,用于检查选中的300x300区域内是否有不可建造的模块。你可以遍历这个区域的每个格子(比如按100x100的单位),检查每个格子的状态。
  2. 使用网格(Grid)系统

    • 维护一个网格系统,记录每个模块的状态(可建造或不可建造)。可以使用一个二维数组来表示这个网格,数组中的每个元素表示该位置是否被占用。
  3. 鼠标点击检测

    • 当玩家尝试建造时,获取玩家鼠标位置并转换为网格坐标。根据选中的模块位置,计算出300x300的区域坐标。
  4. 碰撞检测

    • 在你获取到的300x300区域内,遍历每个格子,查看是否有被标记为不可建造的模块。如果有,则返回一个提示,告诉玩家不能在该区域建造。
  5. 建造逻辑

    • 如果没有冲突,允许建造并更新网格状态,将选中的区域标记为不可建造。
  6. 用户反馈

    • 通过视觉反馈(例如改变颜色为红/绿)告诉玩家选择的区域是否可以建造。
bool CanBuildAtPosition(int startX, int startY, int width, int height) {
    for (int x = startX; x < startX + width; ++x) {
        for (int y = startY; y < startY + height; ++y) {
            if (grid[x][y] == OCCUPIED) {
                return false; // 不可建造
            }
        }
    }
    return true; // 可建造
}

void BuildAtPosition(int startX, int startY, int width, int height) {
    if (CanBuildAtPosition(startX, startY, width, height)) {
        for (int x = startX; x < startX + width; ++x) {
            for (int y = startY; y < startY + height; ++y) {
                grid[x][y] = OCCUPIED; // 标记为已占用
            }
        }
        // 执行建造逻辑,例如生成模块等
    } else {
        // 提示玩家无法建造
    }
}


http://www.kler.cn/news/328068.html

相关文章:

  • 06.C/C++内存管理
  • 【数据库】MongoDB 用户权限与数据之间的关系详解
  • Android studio配置AVD虚拟机
  • 【60天备战2024年11月软考高级系统架构设计师——第33天:云计算与大数据架构——大数据处理框架的应用场景】
  • 关于Java中的List<User>如何进行深拷贝
  • 贝锐蒲公英工业物联方案:助力美的智慧楼宇全球布局
  • Leetcode 611. 有效三角形的个数
  • 前端面试题(八)
  • 音视频入门基础:FLV专题(7)——Tag header简介
  • 【STM32单片机_(HAL库)】4-1【定时器TIM】定时器中断点灯实验
  • 【漏洞复现】JeecgBoot 积木报表 queryFieldBySql sql注入漏洞
  • 【进阶OpenCV】 (2)--Harris角点检测
  • 衡水中学资料大全-重构版(状元、学霸笔记)
  • .NET MAUI(.NET Multi-platform App UI)下拉选框控件
  • UE5: Content browser工具编写02
  • 【抽代复习笔记】29-群(二十三):生成子群的两道例题及子群陪集的定义
  • hdlbits系列verilog解答(Exams/m2014 q3)-77
  • 【qt】QQ仿真项目1
  • 【洛谷】P4551 最长异或路径 的题解
  • 自然语言处理的应用领域有哪些?
  • 【漏洞复现】孚盟云oa AjaxSendDingdingMessage接口 存在sql注入漏洞
  • 云计算 Cloud Computing
  • 前端——DOM与BOM总结
  • macOS开发环境配置与应用
  • vant 数据校验
  • 华为OD机试 - 最长回文字符串 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)
  • ZYNQ: GPIO 之 MIO 控制 LED 实验
  • Qt(9.28)
  • 深入理解 `strtok()` 函数:字符串分割的艺术
  • go语言 常用的web框架