UE4 动态生成网格

news/2024/11/10 10:27:03/文章来源:https://www.cnblogs.com/XTG111/p/18203409

说明

在游戏中动态改变网格数量和形状等,该功能是寻路功能的前期准备,即在基础移动地基上方,构建一层网格,任何移动的操作都可以基于该网格进行计算。从而在编辑器模式下能够更方便进行调试

InstancedStaticMeshComponent

其是一种用于优化静态网格渲染性能的技术。InstancedStaticMesh允许你在场景中高效地渲染大量相同的静态网格对象。每个实例(Instance)共享相同的网格、材质和渲染属性,但可以具有不同的位置、旋转和缩放。
对于每一个网格,可以传入网个参数比如使用的材质,网格类性,碰撞类型和颜色等,进行初始化,然后所有网格初始化完成后调用AddInstanced实现网格的生成。
而为了体现每个网格的颜色,可以利用InstancedStaticMesh的SetCustomDataValue实现对自定义数值的控制,该自定义数值可以影响材质表现,而其需要一个索引即该网格在InstancedStaticMesh中的所有网格的索引。

所以对于每次AddInstance可以使用一个数组来维护当前Add后的网格索引,并且在每次Add之前可以查看当前索引是否已经具有网格,如果有可以删除后再Add

void AXGridMeshInst::AddInstance(const FIntPoint Index, const FTransform Transform, const TArray<ETileState>& states)
{RemoveInstance(Index);InstancedMeshComponent->AddInstance(Transform);int temp = InstanceIncdexes.Add(Index);FLinearColor colorins;float isFilled = GetColorFromState(states, colorins);//UE_LOG(LogTemp, Warning, TEXT("RGB: %f,%f,%f"),colorins.R,colorins.G,colorins.B);InstancedMeshComponent->SetCustomDataValue(temp, 0, colorins.R, false);InstancedMeshComponent->SetCustomDataValue(temp, 1, colorins.G, false);InstancedMeshComponent->SetCustomDataValue(temp, 2, colorins.B, false);InstancedMeshComponent->SetCustomDataValue(temp, 3, isFilled, false);
}

image

对每个网格参数的设置

新建了一个Actor类,GridVisual,其用来控制对InstancedMesh的调用,该类是生成网格的主要类,由于是动态生成网格,所以利用ChildActor组件来接受InstancedMesh,而不是直接声明一个类对象,这是因为一般类对象的构造都是在构造函数中已经利用CreateDefaultObject实现好了,如果想要动态生成可以参考。
而ChildActor组件相对来说比较简单,并且使用后ChildActor对象和GridVisual的关系为松耦合,其实际上可以理解为独立的,更改ChildActor不会影响GridVisual的逻辑。
在GridVisual类中,调用ChildActor中的Initial方法以及Add方法从而实现对于网格的创建。
为了能够使得生成的网格实体不要和地基重叠,还可以设置在Z轴方向上的偏移

void AXGridVisiual::InitializeGridVisual(AXGrid* XGrid)
{if (!ChildActor_GridMeshInst) return;XGridIns = XGrid;XGridMeshInst = Cast<AXGridMeshInst>(ChildActor_GridMeshInst->GetChildActor());if (!XGrid || !XGridMeshInst) return;XGridMeshInst->InitializeGridMeshInst(XGridIns->GetCurrentGridShape(XGridIns->GridShape)->FlatMesh, //通过Grid实例获取StaticMesh类型XGridIns->GetCurrentGridShape(XGridIns->GridShape)->FlatBorderMaterial, //通过Grid实例获取材质FColor::Black,ECollisionEnabled::QueryOnly);//设置网格生成的中心点FVector loc{ 0.0f,0.0f,0.0f };SetActorLocation(loc, false);SetOffsetfromGround(Offset);
}void AXGridVisiual::UpdateTileVisual(FTileDataStruct* Data)
{if (!XGridMeshInst) return;XGridMeshInst->RemoveInstance(Data->Index);//校验该网格类型是否是可以选择的类型 --> 不是障碍物或者为空if (!IsTileTypeWalkAble(Data->Type)) return;XGridMeshInst->AddInstance(Data->Index, Data->Transform, Data->States);
}

image

Grid类

该类是拖入到游戏场景中的类,相当于为了实现动态生成网格,使用了三层层级关系,主要就是想要降低耦合。在Grid类中同样使用ChildActor来实现对GridVisual类的接受,Grid类同样还接受了后面用来处理寻路的类。
为了能够动态生成网格,所以Grid类中必然会有几个参数,网格大小,网格沿X,Y方向的个数,以及是否根据环境生成合理的网格。
这些功能都主要体现在SpawnGrid中。
首先是初始化InstancedMesh所需要的数据,通过传入当前Grid类即可

XGridVisual->InitializeGridVisual(this);

SpawnGrid

生成就是沿着X,Y方向依次生成,所以首先需要通过中心点以及网格参数计算出左小角的起始点。然后通过一个双重for循环,计算出点(x,y)位置上的方格的Transform,然乎传入到AddGridTile中。
如果开启了依靠环境,那么还应当通过射线检测,判断当前地基的方格类型。

AddGridTile

调用GridVisual中的Update方法,传入当前该网格的参数。

void AXGrid::AddGridTile(FTileDataStruct* TileData)
{GridTiles.Add(TileData->Index, *TileData);if (!XGridVisual) return;XGridVisual->UpdateTileVisual(TileData);OnTileDataUpdated.Broadcast(TileData->Index);
}

image

动态生成

为了能够动态生成,使用到了ConstructionScript节点,在节点中获取ChildActor实例
Construction Script 是蓝图类中的一个特殊功能,它允许你在编辑器中设置和调整 Actor 的属性和组件。Construction Script 在你编辑 Actor 时会不断运行,以便实时更新和预览你的更改。这使得它非常适合用于设置和配置场景中的对象。Construction Script 的特点和用途 实时预览:允许你在编辑器中实时预览更改,方便进行调整和调试。动态生成和配置组件:可以在编辑器中动态生成和配置组件,自动化对象的创建和配置过程。初始化设置:为 Actor 设置初始状态和属性,确保在游戏开始时所有内容都已正确配置。
在C++代码中需要使用

#if WITH_EDITORvirtual void OnConstruction(const FTransform& Transform) override;
#endif

来实现该功能
在ChildActor源码中,ChildActor的动态生成功能也是包含在

#if WITH_EDITOR
#endif

这样的宏中,用于在代码中包裹只在编辑器模式下编译和运行的部分。这使得你可以在 C++ 代码中编写特定于编辑器的逻辑,而不影响游戏在非编辑器(即运行时)模式下的行为

后续

创建UI界面,将TileSize,index等数据绑定到UI控件上。

大致调用关系

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/709990.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FormCreate中在事件中获取api

FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。支持5个UI框架,并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定form-create中在事件中获取api FormCreate 是一个可以通过 JSON 生成具…

【最新】别再发邮件了,必须在开源之夏后台申请,50%的人竟然都没有报名成功!

引言 近期我们注意到很多学生朋友通过邮件向导师申请报名,请注意!!!​这是无效的,请必须通过“开源之夏”官方后台申请报名,请仔细参考这篇【报名攻略】 所以,我们特此举办这次宣讲会,目的是向所有感兴趣的学生详细介绍Apache DolphinScheduler社区在开源之夏中提供的项…

Flink富函数

富函数是DataStream API提供的函数接口,Flink的函数都有它的Rich版本,它与其他函数不同的是,富函数可以获取到运行环境上下文,初始化参数,拥有生命周期方法等,可通过它进行自定义复杂功能。我们常见的如RichMapFunction、RichFilterFunction等。富函数的生命周期主要通过…

C#如何用最简单方法调用Python?

最近有群友咨询C#如何调用Python?小编尝试Python.NET过程中遭遇的版本兼容性和环境配置难题,小编决定寻找一个更为简单、稳定且对初学者友好的解决方案。小编搜索一番,除了Python.NET之外,还有其他途径能够帮助我们轻松地在C#项目调用Python脚本,那就是通过命令行调用,使…

创建你的-Mysql-数据库-全-

创建你的 Mysql 数据库(全)原文:zh.annas-archive.org/md5/853FEC9D976A75004408D5A9A661EDD8 译者:飞龙 协议:CC BY-NC-SA 4.0前言 1995 年发布的 MySQL 已成为最受欢迎的开源数据库系统。MySQL 和 phpMyAdmin 的普及使得许多非 IT 专家能够使用 MySQL 后端构建动态网站。…

【Unreal】虚幻GAS系统快速入门

【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!前言最近在用UE做单机ARPG的战斗系统,研究了一下GAS。本文主要介绍GAS各个模块的用途,以及特定功能的多种实现方法。为了让大部分人能…

[CISCN 2022 初赛]online_crt crash漏洞引起的命令执行

几天没做题了,有点生疏。看题吧。题目标签说是CVE-2022-1292,去看看。意思就是在$fname处构造恶意文件名导致的命令注入,而且前面没有认真过滤,也就是文件名命令执行。 看看题目源码:点击查看代码 import datetime import json import os import socket import uuid from …

团队作业5——测试与发布(Alpha版本)

这个作业属于哪个课程 软件工程这个作业要求在哪里 团队作业5——测试与发布(Alpha版本)这个作业的目标 Alpha版本测试报告、发布说明团队Gitee仓库链接 Gitee鏈接团队成员:姓名 学号蔡梓严(队长) 3122004686刘睿 3122004697吴炳辉 3122004709陈翼 3122006207林诗芸 322200…

解锁你的数据库:JPA和Hibernate的乐观锁与悲观锁

哈喽,大家好,我是木头左!引言 在当今的软件开发领域,数据库操作是不可或缺的一部分。然而,随着并发操作的增加,如何正确地处理并发问题是每个开发者都需要面对的挑战。本文将深入探讨JPA(Java Persistence API)和Hibernate这两种ORM(对象关系映射)工具中的乐观锁和悲…

易基因:WGBS+ChIP-seq等表观组分析揭示FOXM1 是抗肿瘤免疫应答的关键调控因子

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 食管癌是一种常见的恶性肿瘤,包括两种主要的组织学亚型:食管鳞状细胞癌(squamous cell carcinoma,ESCC)和食管腺癌(adenocarcinoma,EAC)。近两年来对抗肿瘤免疫应答机制的理解得到了显著提高,免疫检查…

Merry Christmas 礼物

Merry Christmas 圣诞快乐!! 我的圣诞礼物,yes~Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` Merry Christmas 礼物 日期:2020-12-25 阿珏 谈天说地 浏览:340次 评论:3条 M…

2020年迟到的年终总结

我一直在想究竟要不要写年终总结,又该写点什么好呢 纠结了一个多月,这件事一直放在心里,直到前几天和杨小 姐 杰打游戏时,问我:“年终总结写了吗?” 这才让我决定一定要写。Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过…