首页 > 其他分享 >UE4 动态生成网格

UE4 动态生成网格

时间:2024-05-21 12:56:34浏览次数:24  
标签:Index 网格 ChildActor Grid colorins UE4 生成

说明

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

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_EDITOR
	virtual void OnConstruction(const FTransform& Transform) override;
#endif

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

#if WITH_EDITOR
#endif

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

后续

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

大致调用关系

image

标签:Index,网格,ChildActor,Grid,colorins,UE4,生成
From: https://www.cnblogs.com/XTG111/p/18203409

相关文章

  • 生成二维码
    需要的依赖<!--生成二维码所需依赖--><!--https://mvnrepository.com/artifact/com.google.zxing/core--><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId&g......
  • uniApp生成的h5页面禁止浏览器上缩放页面(支持安卓,ios)
    项目场景:uniapph5内嵌原生appios样式问题:1.双击和双指滑动,内嵌的h5页面均会被放大缩小2.修改ios底部的安全距离的背景色,默认是白色问题描述1.双击和双指滑动,内嵌的h5页面均会被放大缩小2.解决ios底部的安全距离和修改背景色,默认是白色解决方案:安卓只需要在h5.template.h......
  • Kmesh进入CNCF云原生全景图,实现网格治理sidecarless化
    本文分享自华为云社区《Kmesh进入CNCF云原生全景图》 ,作者:云容器大未来。近日,Kmesh 正式进入CNCF云原生全景图,位于ServiceMesh 类别下。CNCFLandscape在云原生实践过程中的每个环节帮助用户了解有哪些具体的软件和产品选择,Kmesh进入CNCFLandscape,成为了CNCF构建云......
  • 生成子群阶数问题
    之前看到grass8cow博客中关于GrupaPermutacji这道题做法的简略记述后一直感觉这个题是究极神秘题。APIO听了Kubic的讲课(当时讲的是LOJ177生成子群阶数)后终于算是懂了一点了。众所周知,所有有限群同构于一个置换群的子群。当我们拿着一堆置换,然后再复合来复合去,所有可能......
  • NumPy 数组排序、过滤与随机数生成详解
    NumPy数组排序排序数组排序数组意味着将元素按特定顺序排列。顺序可以是数字大小、字母顺序、升序或降序等。NumPy的ndarray对象提供了一个名为sort()的函数,用于对数组进行排序。示例:importnumpyasnparr=np.array([3,2,0,1])print(np.sort(arr))输出:[0......
  • Liunx下通过netcore接口生成前端图片的问题。
    用netcore来生成前端微信Native支付的二维码。1、首先CentOS7.0要安装libgdiplus,命令如下:yuminstalllibgdiplus-devel,然后重启netcore服务。//这个地方要注意,网上有不少例子的下载命令是错的,有的时候安装不上。2、Vs代码使用QRCoder库,代码如下publicstaticMemoryStream......
  • axis2生成wsdl回执参数首字母大小写问题
    在跟局方对接接口的时候,局方回执我的wsdl接口,发现收不到同步回执,怀疑问题为回执参数首字母小写导致  代码中的参数对象首字母确实是大写,但生成的wsdl文件确变成了小写,目前是用axis2生成的参考:https://bbs.csdn.net/topics/390457284发现了变为小写的原因,选择使用xFire......
  • Amazon Q Developer 实战:从新代码生成到遗留代码优化(上)
    本文将探索如何在VisualStudioCode这个开发者常用的一种集成编程环境(IDE)中,使用AmazonQDeveloper列出指定区域的AmazonS3存储桶的示例代码实现。我们将从在AmazonQDeveloperAgent的协助下,从生成新代码开始,到将生成的新代码与现有的低效“遗留”旧代码进行性能对比;......
  • 【.NET项目分享】免费开源的静态博客生成工具EasyBlog,5分钟拥有自己的博客
    EasyBlog说明本博客系统通过构建工具生成纯静态的博客网站,借助GitHubPages,你可以在5分钟内免费拥有个人博客。它具有以下特点生成纯静态网站,访问速度极快使用markdown格式来编写博客内容基于git代码管理来存储你的博客使用CI工具来自动化部署你的博客站点效果展示:NilTo......
  • 人工智能帮你一键生成完美架构图
    简介架构图通过图形化的表达方式,用于呈现系统、软件的结构、组件、关系和交互方式。一个明确的架构图可以更好地辅助业务分析、技术架构分析的工作。架构图的设计是一个有难度的任务,设计者必须要对业务、相关技术栈都非常清晰才能设计出来符合需求的架构图。实践演练有明确的......