虚幻引擎(UE5)-大世界分区WorldPartition教程(四)

news/2024/11/9 1:53:53/

文章目录

  • 前言
  • 一、Data Layers的使用
    • 1.添加Actor到Data Layers
    • 2.运行时处理
  • 总结


上一篇:虚幻引擎(UE5)-大世界分区WorldPartition教程(三)

前言

Data Layers(UE4中叫Layers)用于将Actor划分到不同的Layer中,通过在编辑器和运行时激活和停用某些数据层,有条件地加载世界数据来组织大世界,前面提到的划分Cell是对WP关卡的横向划分,DataLayer是对WP关卡的纵向划分

该系统提供了一种对资源进行分组管理的方式,比如可以将建筑放到一个Layer中,将植被放到另一个Layer中,并且在编辑和Gameplay层都可以操作这个Layer,这不但方便了编辑管理世界,而且开发人员也可以在Gameplay层做一些比较有趣的玩法,比如白天和黑夜系统,荒野和城市互换等


提示:以下是本篇文章正文内容

一、Data Layers的使用

1.添加Actor到Data Layers

再上方工具栏中找到 Window->World Partition->Data Layers Outliner,然后在Data Layers Outliner中右键创建新的DataLayer

在这里插入图片描述
在这里插入图片描述
新建DataLayer后在面板中的数据层资产中 创建数据层:
在这里插入图片描述
在这里插入图片描述
然后在Actor的Details面板中为Actor指定Data Layers:
在这里插入图片描述
这里需要注意的是,Data Layers只有在编辑WP关卡时才生效,如果是普通关卡,需要像UE4那样在Layers中添加

在这里插入图片描述

这个时候返回数据层面板中就可以根据策略去加载了,可以控制初始显示和隐藏等等,也能通过蓝图去控制显示方式。

2.运行时处理

Data Layers数据是由UDataLayerSubsystem负责管理的,具体处理如下:

前后端分开:

void UWorldPartitionStreamingPolicy::UpdateStreamingState()
{//前后端对Cells处理的逻辑分开if (NetMode == NM_Standalone || NetMode == NM_Client || AWorldPartitionReplay::IsEnabled(World)){  //前端对StreamingCells的处理,GetStreamingCells会处理DataLayer的Cellif (WorldPartition->IsInitialized()){WorldPartition->RuntimeHash->GetStreamingCells(StreamingSources, FrameActivateCells, FrameLoadCells);}}else{//后端对SteamingCells的处理,这里会处理归属DataLayer的Cellconst UDataLayerSubsystem* DataLayerSubsystem = WorldPartition->GetWorld()->GetSubsystem<UDataLayerSubsystem>();//处理不属于DataLayer的Cells和以及归属于状态为Activate的DataLayer里的Cells,放入ActivateStreamingCells中WorldPartition->RuntimeHash->GetAllStreamingCells(ActivateStreamingCells, /*bAllDataLayers=*/ false, /*bDataLayersOnly=*/ false, DataLayerSubsystem->GetEffectiveActiveDataLayerNames());//只处理DataLayer中的Cells,并放入LoadStreamingCells中if (DataLayerSubsystem->GetEffectiveLoadedDataLayerNames().Num()){WorldPartition->RuntimeHash->GetAllStreamingCells(LoadStreamingCells, /*bAllDataLayers=*/ false, /*bDataLayersOnly=*/ true, DataLayerSubsystem->GetEffectiveLoadedDataLayerNames());}}
}

前台处理部分:

bool UWorldPartitionRuntimeSpatialHash::GetStreamingCells(const TArray<FWorldPartitionStreamingSource>& Sources, UWorldPartitionRuntimeHash::FStreamingSourceCells& OutActivateCells, UWorldPartitionRuntimeHash::FStreamingSourceCells& OutLoadCells) const
{//先拿到当前世界所有的DataLayersconst UDataLayerSubsystem* DataLayerSubsystem = GetWorld()->GetSubsystem<UDataLayerSubsystem>();//如果没有StreamingSource的话,处理所有的StreamingGrid中的AlwaysLoaded Cells,if (Sources.Num() == 0){for (const FSpatialHashStreamingGrid& StreamingGrid : StreamingGrids){if (!StreamingGrid.bClientOnlyVisible || bShouldConsiderClientOnlyVisible){/*这里处理了归属于DataLayerSubsystem的Cell,具体处理逻辑:1.如果不归属于DataLayer且被设置为IsAlwaysLoaded的Cell和归属于DataLayer且它被设置Activated的Cell被放入OutActivateCells中2.如果归属于DataLayer且它被设置Loaded的Cell被放入OutLoadCells中*/StreamingGrid.GetAlwaysLoadedCells(DataLayerSubsystem, OutActivateCells.GetCells(), OutLoadCells.GetCells());}}}else{//获取所有基于StreamingSource的Cellfor (const FSpatialHashStreamingGrid& StreamingGrid : StreamingGrids){if (!StreamingGrid.bClientOnlyVisible || bShouldConsiderClientOnlyVisible){/*这里会根据StreamingSource设置的形状(这个可以在组件中设置Shapes,默认情况是用以StreamingSource作为圆心,以Grid的LoadingRange作为半径构成圆)来判断是否与Cell相交,具体逻辑:1.首先根据传入的Coords,获取该坐标出的Cell,并GetBuounds2.判断是否相交,具体逻辑在FSquare2DGridHelper::FGrid2D::ForEachIntersectingCells中,这里会涉及到Cell的划分3.如果不归属于DataLayer且被设置为IsAlwaysLoaded的Cell和归属于DataLayer且它被设置Activated的Cell被放入OutActivateCells中4.如果归属于DataLayer且它被设置Loaded的Cell被放入OutLoadCells中5.调用GetAlwaysLoadedCells方法,如前所述,不累述*/StreamingGrid.GetCells(Sources, DataLayerSubsystem, OutActivateCells, OutLoadCells);}}}
}

如果是要在Gameplay中使用DataLayer的话调用UDataLayerSubsystem::SetDataLayerRuntimeState方法即可,大家可以自己尝试一下

总结

其中总的来说Data Layers实际上就是UE4中的Layers系统的Puls版,它可以方便的实现同个世界的不同变体,不仅方便编制者管理复杂的世界,同时也能在Gameplay中实现有趣的玩法以上就是今天要讲的内容

到此虚幻引擎(UE5)-大世界分区WorldPartition教程暂时完结了 To be Continued …


http://www.ppmy.cn/news/634280.html

相关文章

玩转代码|那些实用的JavaScript单行代码,帮你轻松工作

目录 数组去重 从url获取参数并转为对象 检查对象是否为空 反转字符串 生成随机十六进制 检查当前选项卡是否在后台 检测元素是否处于焦点 检查设备类型 文字复制到剪贴板 获取选定的文本 查询某天是否为工作日 转换华氏/摄氏 两日期之间相差的天数 将 RGB 转换为…

大学生的期望落差在哪里?——转帖newsmth

大学生的期望落差在哪里&#xff1f;——以北京大学的情况为例ZZ l 2008年下半年以来&#xff0c;大陆舆情在一些人利用一些事件的操作下&#xff0c;急剧恶化。2010年&#xff0c;中国大陆的媒体人控制的舆情进入“末世时代”&#xff0c;与中国在国际上的地位——包括经…

微分方程应用——笔记整理

首先&#xff0c;根据正常思路走&#xff0c;化简得到式子&#xff1a; 不难发现&#xff0c;设 后面得出该方程的通解&#xff1a; 这里要注意什么等于这个通解 --- z 又因为该曲线过点 所以可以求出c为3 该题虽然简单&#xff0c;但是要注意几个问题&#xff0c;该定…

小白也能看懂的高性能计算概念解说

高性能计算就像一台超级汽车&#xff0c;它不仅拥有强大的引擎和速度&#xff0c;还能应对复杂的道路和挑战。想象一下&#xff0c;你是一个对汽车只有基本了解的小白&#xff0c;然后有人告诉你关于高性能计算的概念&#xff0c;让我们用比喻来帮助你理解。 想象一辆普通的家用…

普及ARM架构芯片的知识

关于ARM架构芯片的知识 嵌入式设备的芯片常采用ARM的架构&#xff0c;它通常包括三个部分&#xff0c;即CPUGPUDSP。 EPISODE ONE CPU常用的架构有ARM9&#xff0c;ARM11&#xff0c;诺基亚的手机多采用的是ARM11架构的CPU。这两者采用的指令集为ARMv5。新一代的架构有Cortex …

Java 对象存储

Java是一种面向对象编程语言&#xff0c;它提供了类和对象的概念来组织和管理代码。在Java中&#xff0c;类是一种用户自定义的数据类型&#xff0c;它包含了属性和方法。对象是类的实例&#xff0c;可以通过调用对象的方法来操作对象的属性。在本文中&#xff0c;我们将深入探…

JavaScript面向对象编程(二)构造函数和类

new关键字和构造函数 在文章JavaScript面向对象编程&#xff08;一&#xff09;原型与继承中讨论啦JavaScript中原型的概念&#xff0c;并且提到了new关键字和构造函数。利用new关键字构造对象的实例代码如下&#xff1a; //define a constructorvar Func function(name,id){…