Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >UE5的World Partition

UE5的World Partition

作者头像
quabqi
发布于 2024-01-07 02:41:59
发布于 2024-01-07 02:41:59
3.3K0
举报
文章被收录于专栏:Dissecting UnrealDissecting Unreal

世界分区,是UE5给大世界项目提供的一套新的解决方案。相比于UE4的WorldComposition有了非常多的改进。官网也有很具体的介绍:

虚幻引擎中的世界分区 | 虚幻引擎5.3文档 (unrealengine.com)

毕竟这个功能也出来了很久了,到处也都能搜到很多关于World Partition相关的基础教程,因此一些基础的使用方法我就不详细去说了。相比于过去WC的解决方案,从我的使用感受来说,我觉得最值得说的方面主要是场景空间划分,Streaming,OFPA存储,DataLayer,LevelInstance,HLOD,WorldPartitionBuilder以及ContentBundle这几个方面,因此下面主要围绕着这些点写一些代码阅读笔记和心得。

场景空间划分

空间划分,主要是指的是怎样去用一种更效率的方式来划分场景。

在没有做场景空间划分的时候,我们想要去做一些关于场景相关的需求,比如获取玩家最近100米的所有Actor,那么就只能去遍历场景内所有的Actor,依次和玩家比较距离,将100米的Actor都删选出来。如果场景内的Actor数量非常庞大,那这个遍历操作就会非常的耗时。假如我们去对场景画格子,每100米是一个格子,那么在做搜索距离玩家最近100米的所有Actor这个需求时,我们就可以先找到玩家在哪个格子,然后把玩家附近的格子里所有Actor取出来依次判断距离,这样就不需要遍历场景内所有的Actor了,能减少很多的计算量,提升了性能。WP所做的场景空间划分也就是一种这样的画格子的方法,在引擎里这个方法叫做Hierarchical HashGrid。

这个画格子的算法和传统的画格子的方法有什么区别呢?或者说相比于传统的画格子方法他改进了什么?既然叫做Hierarchical HashGrid,那么改进的点其实就和Hierarchical以及Hash这两个关键词有关系。传统画格子的方法主要有下面这两个问题:

  1. 一定会有大量的格子是空的,那么这些空格子的存储,必然会造成了内存浪费。比如为10*10的格子创建了一个二维数组,可能只有少量几个格子有Actor,那么这个二维数组大量的内存就浪费掉了。
  2. 有些Actor的Bounds会特别的大,横跨了好几个格子,那么这个Actor属于哪个格子呢?

因此Hierarchical HashGrid就针对这两点给了一个改进的画格子方案。大量的格子都是空的,那么就不要去存储空格子的空间。可以类比TArray和TSet的区别:在一维的情况下如果用TArray存储格子x坐标,0~100放到元素0,101~200坐标放到元素1,依次放下去,那么整个场景的Actor都可以放到指定的一个格子里。但如果整个一维场景的Actor坐标分布不是那么均匀,一定有很多格子是空的,空的数组元素的内存就浪费了。如果用TSet存储格子,内部其实是按照编号对应的Hash值来索引的,那么这些空的格子,就不会分配实际内存,这样就能节省很多空间。那么把这个方式扩展到平面和空间上,也就是对格子格子(x,y或x,y,z方向的编号)建立hash,存到一个TSet里,相比于二维数组来说就节省了很多的空间,这样就解决了上述的第一个问题。

对于有些Actor的Bounds特别大的情况,我们可以在小格子的基础上,建立更大范围的格子。比如已经有了100米的格子发现放不下这个Actor,我们可以再建立200米的格子尝试去放,如果放不下再尝试建立400米的格子去放,直到最后一个格子,肯定和整个地图一样大,那么必然能够放下这个Actor。这种方式就叫做Hierarchical。因为第一步,我们已经使用了Hash去存储格子,我们可以将这个hash值扩展一下,用格子(x,y,z方向的编号,层级l)这样的4元组作为key建立hash,去存储整个空间结构,那么最终就解决了上述的两个问题。

World Partition内部就是通过这样的一种方式去管理空间的。除了WorldPartition,UE5还有很多其他模块也是这样管理的,包括SmartObject,ZoneGraph等。具体可以看HierarchicalGrid2D.h,这个是通用的容器,项目也可以直接复用。而WP的实现在WorldPartitionRuntimeSpatialHash.h里的FSpatialHashStreamingGridLevel。如下图所示:

LayerCellsMapping就是xy的索引,映射到LayerCells数组的下标。本质上和上面说的Hierarchical HashGrid是一回事。

当然Hierarchical HashGrid这种方式也可能会引起一些BUG:有些覆盖到x,y坐标轴上的Actor,永远都处于加载状态,无论什么情况都不会卸载。根据上面的算法我们也很容易就能理解,就是因为WP在画格子的时候是轴对齐的,这些覆盖轴的Actor没法放到一个合适的格子里,最终被放到了和整个场景一样大的那个最大格子里,这个最大的格子当然也就是覆盖玩家的位置,所以这些Actor永远不卸载,下面有写5.3的解决方案,低版本可以根据这个原理手动改。

游戏里可以点击Preview Grids去看当前加载的格子,下面Cell Size可以调整Level 0的格子大小,Level 1的格子默认就是0格子的2倍,从下图就可以看到当前加载的格子。Loading Range就是加载的距离,也就是图里圆圈的半径,扫到的格子就是处于加载的状态。

Use Aligned Grid Levels这个一定要选Disabled,从上面两张图也能看到,两层level的格子边界是没有对齐的,而如果是Enabled,就能看到多层格子坐标严格按照边界对齐。因为每一级的格子如果是对齐的,就会导致覆盖坐标轴的Actor永远卸载不掉,因此Disabled能解决这个问题。

GenerateStreaming

我看的是5.3的代码,老版本的代码流程差不多但功能确实有不少缺失。WP的入口是UWorldPartition这个类。这个对象本身是挂在AWorldSettings上面的,配置以及运行时基本都在这个类里,引擎为这个类定制了编辑器,所以能在WorldSettings页签里显示。

在PIE启动游戏加载场景时候,会触发OnBeginPlay函数,最终会调用到UWorldPartitionRuntimeSpatialHash的GenerateStreaming函数。这个函数就是生成地块的地方。PIE下会生成到/Memory开头的Package里,打包的时候会调用到UWorldPartition::GatherPackagesToCook,这里也会生成对应每个Cell的Package,然后逐个Package保存对应的数据。

因此WorldPartition底层其实还是通过UE4原来的那套levelStreaming机制去动态加载和卸载。cook的结果其实也和老的子level地块是一样的,只不过这个划地块变成实际资源的过程被WorldPartition自动做了,在编辑器下很特殊,是直接在内存里建立了对应地块的。下面可以看到,UWorldPartitionRuntimeLevelStreamingCell内部这个类继承的是LevelStreaming对象,内部和ue4的大地图加载是同样的机制。

在这个阶段,最重要的事情就是对所有的Actor做空间划分,每个Actor都会根据自己所在的位置以及包围盒大小放到实际的Cell中,如果多个Actor有引用关系,那么有引用关系的Actor会被打到同一个Cluster中。这里要注意的是,引用关系是指,引用别的Actor以及被Actor引用这两种情况。

一般多个Actor的引用是不能跨DataLayer的,否则在加载的时候会出现问题。如果引用跨了多个DataLayer,那么会在打开地图时候报MapCheck的Error,这些Actor实际很有可能就不会随着DataLayer加载了,而是只要对应Cell加载出来就会直接把这些Actor直接加载出来。

这个具体原因是,WP的逻辑是先划分Cell,然后再看Cell内所有Actor属于哪个DataLayer,然后再决定这个Cluster属于哪个Cell。具体的划分结果,可以通过Saved/Log/WorldPartition/下找到详细的log。因为GenerateStreaming的执行时机是在PIE启动时候或者cook的时候,所以一定要先运行一次游戏才可以看。这个文件也是检查WP的BUG各种加载问题的利器。对于5.3版本的引擎,也可以使用wp.Editor.DumpStreamingGenerationLog输出一次,这个指令可以不运行游戏即可输出结果。

具体如下,是Lyra的一个地图的信息:

前面一段,记录了当前地图内所有的Actor的ActorDesc信息。

然后是Clustor的分组信息,这个信息很重要,可以看到哪些Actor被分到了一组。

然后是地块信息,上面这个是Persistent Level,也就是随着地图启动就进来,永远不卸载的Actor。

这里是地图分块的统计信息,具体分了多少个Level,每个Level里多少个Cell,每个Cell里多少个Actor等。

然后就是每个Grid里面,每个Cell的分组信息。可以看到上图是MainGrid,L0_X0_Y-1这个Cell的Actor信息。前面也具体讲了L0_X0_Y-1,就是HashGrid的key,L0就是最小的一级地块,L1的大小是L0的2倍。然后X0_Y-1就是xy坐标的编号。

如果有Runtime类型的DataLayer,那么在生成的时候就会看到这样的Cell,除了Cell的编号外,还有一段DL开头的。这个就表示这个Cell内是有DataLayer的。因此同一个Cell,也会按照DataLayer来进行拆分。所以这也解释清楚了上面的问题,为什么一个Actor引用了另一个DataLayer里的Actor会导致这个Cluster不知道放哪里了。因为Cluster肯定要放在一个Cell下面才行。

UpdateStreamingState

在运行时,每帧都会调用到UWorldPartitionSubsystem::UpdateStreamingState()函数,这个函数内部就是在根据当前的StreamingSources来更新哪些地块需要加载和卸载。也会调用到每个WordPartition的UWorldPartitionStreamingPolicy::UpdateStreamingState()函数。算法很简单,其实就是根据source算距离,看哪些Cell需要ToLoad和ToActivate,然后再跟上一帧已经Load和Activate的Cell做diff,diff得到的结果就是这帧需要Load和Activate的Cell列表;然后用上帧已经Load的Cell列表和这帧ToLoad/ToActivate的列表做diff,diff得到的结果就是这帧需要UnLoad的Cell列表。

Load和Activate就和老的levelStreaming做的事情是一样的。Load就是加载资源,Activate就是把地图变为可见并AddToWorld。

OFPA(One File Per Actor)

一个文件一个Actor的底层实现,其实是调用Actor的SetPackageExternal(true)来设置的,内部会对这个Actor创建一个独立的Package,并在原来的Object的Flag上标记RF_HasExternalPackage。这个独立的Package会保存在"Content/__ExternalActors__/"这个文件夹下,如果Actor有保存在文件夹内,那么文件夹本身的这个对象,也会存在"Content/__ExternalObjects__"这个文件夹下。这两个文件夹在引擎的ContentBrowser里看不到。

有一个专门的类FExternalPackageHelper会处理具体的保存和读取工作。

最终会根据是不是Actor选择对应文件夹。

每个Actor,在WP下会额外创建一个FWorldPartitionActorDesc。这里保存了当前Actor的和WP相关的基本信息,包括自己的Guid,名字,路径,基类,Native基类,以及其他Actor的References,自己所在的DataLayer等。

WP在建立Cluster的时候,就是依赖这个References以及对应的DataLayer的信息来处理的。具体来说,就是A引用了B,那么把这个单向关系变成双向的画一个连通图出来,那么Graph所有有连通的就是一个Cluster,最后就是一个Cluster列表。具体可以参考下面这个函数的算法:

DataLayer

虚幻引擎中的世界分区 - 数据层 | 虚幻引擎5.3文档 (unrealengine.com)

datalayer,其实就是取代ue4的layer功能的,可以把一批Actor放在一个DataLayer下,这样程序就可以在运行时动态加载。但和ue4的layer不同的是,一个Actor可以属于多个DataLayer。

这里要注意区分Editor还是Runtime类型的。如果是Runtime就会要求额外是定运行初始状态。

用DataLayerManager的下面这些函数,就可以在运行时控制加载卸载了。也有个委托可以去监听DataLayer的状态。这些函数都可以通过蓝图来调用。

LevelInstance

这个是ue5的一个新的机制,有点类似unity的prefab。具体可以看文档:

虚幻引擎中的关卡实例化 | 虚幻引擎5.3文档 (unrealengine.com)

本身使用起来还是挺简单的。我觉得比较适合使用LevelInstance的场合就是拿来做地图上的兴趣点,假如有多个同样的兴趣点,且内容都差不多,那么就可以做成一个LevelInstance,然后把这个LevelInstance摆到地图的各个地方来复用。也可以用来实现动态关卡,不同的时候加载不同LevelInstance。

另一个比较重要的功能,我觉得就是可以用LevelInstance来搞子关卡蓝图。在ue4的时候,每个子关卡都可以有个自己的蓝图,但是ue5的WorldPartition都是一个大关卡了,那么正常情况只有一个关卡蓝图,这对于策划来说是很坑的。但是如果对于不同的兴趣点,把相关的Actor包到一个LevelInstance里,就可以在这个LevelInstance里面去写这个兴趣点专有的蓝图了。

另外就是理论上可以对WorldPartition做静态烘培。LevelInstance本身就是一个普通关卡因此可以去单独烘BuiltData,WorldPartition里如果包了多个带烘培BuiltData的LevelInstance,那么是不是就可以让WorldPartition就支持了多套静态烘培?不过我也没尝试这么做过,不一定说的对,希望有做过这方面的同学能一起探讨。

还有个比较好用的类就是APackedLevelActor,这个类会让内部所有的Actor自动按不同Mesh合Instance,在摆到WorldPartition的大地图里面,就是合批后的一个Actor,而直接打开这个levelInstance,就是合批前的那些Actor,同时也因为有对应的关卡蓝图,这个关卡蓝图可以去控制合批的细节,相当于是官方提供的一个手动合批工具,非常好用。

最后就再来说说LevelInstance的存储。LevelInstance本身就是一个子level,所以是单独存成了一个umap资源,可以认为这个子level就是CDO,对于unity来说就是prefab本身。而把LevelInstance拖到关卡里面,内部的Actor就会额外产生ExternalPackage,也就是说在__ExternalActor__路径下会有LevelInstance的每个Actor资源。umap和WorldPartition内部的这些单Actor的文件,可以理解为CDO和实例对象的关系,因为同一个LevelInstance可以在关卡内摆多个,也就相当于多个实例对象。

HLOD

hlod可以看官方文档:

虚幻引擎中的世界分区 - 分层细节级别 | 虚幻引擎5.3文档 (unrealengine.com)

是可以分多级HLOD的,每一级可以选择单独的烘培方式,合instance,合mesh,或者是减面合mesh。

这里要注意的是,HLOD会自己额外建立对应的Grid,内部也有自己的Cell,不会放在MainGrid内也不受WorldSetting的规则影响,而是受HLOD Layer这个配置文件影响。然后HLOD的实现是通过WorldPartitionBuilder方式实现的。

WorldPartitionBuilder

这个其实是个编辑器的Commandlet脚本。因为WorldPartition在编辑器层面每个Actor是OFPA,而打包后就是和ue4本身的地图没区别了。就相当于是对编辑器地图做了一个cook操作,生成实际的发布地图。因此WorldPartition提供了这样一个工具,让程序员可以也自定义一些操作,对编辑器地图做一些自定义的处理,然后把结果保留下来。

自带了这几个功能,包括烘培HLOD,烘培小地图,烘培植被,烘培RVT等:

一些插件里也有一些Builder,包括SmartObject的,可以批量收集全图的SmartObject到对应的Collection里。

当然除了引擎提供的功能以外,我们也可以去自定义Builder,比如在这里做一些剔除合并Actor,或者合批工作,以及做一些和地图性能优化相关的功能,就可以让地图开发工作变得很方便。也可以去做一些数据收集工作,比如统计场景内各个兴趣点,指定Actor类型并整理成报告,去做一些静态分析等。

随便找一个Builder,可以看到其实只需要Override这几个函数就可以实现对应的需求了。其中GetLoadingMode是告诉Commandlet怎样处理对应地块的

其中Custom/EntireWorld可以一次处理一整块地图,IterativeCells/IterativeCells2D可以分Cell处理,如果分Cell,就会多次调用RunInternal函数。在RunInternal内部可以通过传统方式TActorIterator遍历当前地块内的Actor,也可以通过FActorDescContainerCollection::TIterator(WorldPartition)去遍历所有Actor的ActorDesc。

ContentBundle

这个功能肯定有人好奇是什么,官方连文档也没有,但是ue5的WorldPartition里还提供了一个编辑器。

其实这个功能是给GameFeature用的。我们知道GF可以动态给游戏增加很多原来没有的功能,而对于WorldPartition,就可以通过ContentBundle给原来的关卡里动态新增一些Actor,这样我们工程就可以只做一个基础的地图,而动态可变的部分都通过ContentBundle来实现。

具体来说,就是在GameFeatureData的配置文件里,新增一个Action,这个Action要选Add World Partition Content。然后就可以去编辑这个ContentBundleDescriptor了。

可以看到这里什么都没,就一个名字,把名字改成我们想要的就好了,然后保存重启编辑器。然后在ContentBundlesOutliner里面就能看到了刚才加好的ContentBundle了

之后,我们就可以给这个ContentBundle里面放Actor,这些Actor就会随着GameFeature的生命周期。

至于怎么放,目前没特别好的办法,只能先把ContentBundle设为当前编辑器的Context然后再设置。具体可以看下面这个介绍,怎么来设编辑器的Context:

虚幻引擎中的Actor编辑器上下文 | 虚幻引擎5.3文档 (unrealengine.com)

在源码层面,ContentBundle的Actor也是单独管理的。在加载卸载的时候都有做特殊处理。然后这些Actor也是存储在插件下面的__ExternalActor__文件夹下的,而不是主地图本身的__ExternalActor__下面。

不过要注意的是,ContentBundle是不支持LevelInstance的,另外也有小道消息听说这个功能会在ue5.5被干掉,所以要不要把这个功能用到自己项目里,就还是看自己项目实际情况来考虑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
UE5 创建Level并实现Level Streaming(新手向)
UE5常见的Game Templates默认启用了新的World Partition的关卡组织方式。如果想在UE5中,试验UE4的Level Streaming,则需要从头创建一个新的关卡。有需要的同学可以参考如下步骤。
JohnYao
2023/03/24
2.2K0
UE5 创建Level并实现Level Streaming(新手向)
UE4/UE5 动画的原理和性能优化
动画在UE4/UE5项目中,往往不仅是GPU和渲染线程开销大户,也是游戏线程的开销大户。按照我的经验,大型游戏项目(尤其是手游)做到中后期,整个项目优化工作做的差不多的时候,你应该也会发现动画的开销会占到整个GameThread的二分之一到三分之二。动画到底是做了什么呢会产生这么多的开销?项目里关于动画的优化也是最容易扯皮的一件事,开发给美术说要砍资源,减少骨骼数,要减少蒙皮面数,否则游戏跑不动,而美术说骨骼数不够根本做不出好的效果,不能优化。但是为什么骨骼数,蒙皮面数会影响到动画的性能呢?难道除了砍资源之外,就没有别的优化手段了吗?为了回答这些问题,我觉得很有必要说一说动画在虚幻引擎内部的执行流程,最后也会说下我在虚幻引擎动画这块推荐的优化手段。
quabqi
2022/09/19
6.1K1
UE4/UE5 动画的原理和性能优化
Python大师!UE5的御用布景师
虚幻引擎已经拥有了蓝图和C++进行开发,为什么还需要Python呢?python相对蓝图和C++有什么优势呢?我认为有以下几点原因: 1、python语言入门简单 2、在虚幻中引入python,可以把海量python生态的库引入到虚幻,这大大加快了开发效率 3、python可以实现虚幻编辑器中自动化工作流程 4、Python目前已经成为制作流程和3D应用程序之间的互操作性的首选语言
Jean
2022/11/25
2K0
Python大师!UE5的御用布景师
UE5入门 00 什么是UE5
UE,英文全称Unreal Engineer,中文全称虚幻引擎,5是UE的最新版本。它是由Epic Games开发的一款全面的游戏开发平台。它不仅被广泛应用于游戏行业,还扩展到了电影、建筑可视化、教育等多个领域。2024年热度最高的3A游戏“黑神话悟空”就是由UE5制作。
90后小陈老师
2024/09/06
1.8K0
UE5入门 00 什么是UE5
UE4/UE5的崩溃,卡死等问题处理
虚幻引擎的业务逻辑开发基本上都是用C++/蓝图,当因为项目代码写的不好遇到Crash等问题时,如果不了解Native程序和引擎底层的一些机制,相比用C#开发业务的Unity或其他完全基于脚本虚拟机的游戏确实要难处理一些。因为业务和引擎代码本身都是基于C++,所以对于解决常规C++的Crash的方法虚幻引擎完全适用,除此外引擎在异常处理上相比于普通的C++程序还是提供了一些额外的方法和工具。本文主要介绍虚幻引擎在处理Crash时的一些做法和经验技巧。
quabqi
2022/10/05
5.6K0
UE4/UE5的崩溃,卡死等问题处理
UE5的StructUtils
StructUtils是UE5新增的一个针对结构体存储和反射的辅助插件。之前在说UE5的ECS框架Mass时有粗略提到这个插件里的相关内容,比如Mass在实现ECS的Component就是使用了FInstancedStruct来保存元信息。有了FInstancedStruct,Component不必在C++预先定义好,可以直接在蓝图进行定义或组合,甚至让ECS支持lua或其他脚本都很容易,相比于其他C++常见的ECS框架,这也是UE5的ECS很有优势的一个点。
quabqi
2023/03/07
2.5K0
UE5的StructUtils
UE4 WebUI插件使用指南
在开发数字孪生应用程序的时候,除了三维场景展示之外,也需要开发丰富和酷炫的2D页面。 使用UE4的UMG开发图表显得比较笨拙。 而通过Web插件允许开发者创建丰富的基于Web HTML5的用户界面,它由内置在UE4中的web浏览器提供支持,包括对Windows、Mac、Linux、Android和iOS的支持。 基于这种插件技术,普通的前端开发人员也可以开发UE4界面上丰富的2d页面效果。
用户3158888
2023/01/08
3.1K0
UE4 WebUI插件使用指南
UE5 猎户座漂浮小岛 06 角色
获取文字、素材资料等,关注微信公众号“90后小陈老师”,回复“漂浮小岛06”#UE#虚幻引擎#游戏开发
90后小陈老师
2024/11/04
1100
UE5 猎户座漂浮小岛 06 角色
虚幻摸鱼周报 #14 | 20231019
在奥林匹克禁区,你唯一可以依靠的就是你的汽车。这片禁区曾是前景广阔的新技术试验场,如今却成了狂暴天气、怪异事件和超自然景象的发源地。在进入该地区探究关于它的流言后,你发现自己被困在其中,而一辆破旧的旅行车是你唯一的希望。
HelloWorld杰少
2023/10/25
2190
虚幻摸鱼周报 #14 | 20231019
Epic Games发布虚幻引擎5,史诗级游戏画面堪比电影镜头!
Epic Game官方发布的视频中,一段在PlayStation 5上的实时demo,让我们见识到实时的游戏画面,竟然可以跟电影镜头比清晰度,和物理世界比真实感!怪不得网友直呼:太过瘾了,超出现有游戏画面一个量级!
新智元
2020/05/19
1.7K0
Epic Games发布虚幻引擎5,史诗级游戏画面堪比电影镜头!
UE4: 学习虚幻引擎4的16条准则
选文 | 朱颜夫 校对 | 吴金忠 翻译 | 朱颜夫 xiaoshen yan 作为一个完全的新手,尝试去学习一个新的游戏引擎看起来会很可怕。你拥有了许多的学习教程、文件和建议,但是你却不明白怎样去开始或是以一个什么样的步骤去学习虚幻引擎4。你在不同的方向间摇摆不定,最终你会越来越迷惑和受打击。 我花费了许多的时间去重构那些从零开始学习游戏引擎的方法。那些方法就是你最初需要关注什么、哪些是你现在需要避免的。 虚幻引擎4是一个完全的游戏引擎。它是一款极度深奥且复杂的软件,可以用来创造各种类型的游戏、环境、电影
大数据文摘
2018/05/25
3.6K0
UE4之UFUNCTION介绍
UObject 或蓝图函数库可将成员函数声明为UFunction,方法是将 UFUNCTION 宏放在头文件中函数声明上方的行中。
李小白是一只喵
2021/05/13
2.6K0
UE5 中用 Python 接口创建 Level Sequence 与设置 TriggerEvent
遇到了一个美术需求,需要批量读取一段动画,制作成 UE 中的 Level Sequence,然后给动画添加几个 Event Track。随后,需要在 Event Track 中添加 Trigger Event,设置插件 uDraper 布料的缓存数据路径。总之,最终效果如下:
太阳影的社区
2022/10/31
3.9K0
UE5 中用 Python 接口创建 Level Sequence 与设置 TriggerEvent
UE5的ECS:MASS框架(三)
前面两篇基本上已经把MASS的ECS基础框架都说清楚了。其中最关键的部分:Fragment/Tag等对应的就是传统ECS中的Component,Processor对应的就是传统ECS中的System,而上层的MassGameplay,MassAI,MassCrowd都是基于底层的ECS框架做出来的Gameplay框架,这一篇主要来说下MassGameplay框架的实现。
quabqi
2022/04/02
7.5K0
UE5的ECS:MASS框架(三)
UE5的初体验
10分钟左右,下好开冲!然后就出现了下面这个熟悉的界面,但UI换成了新风格,还挺酷的。
quabqi
2021/11/04
1.1K0
UE5的初体验
【UE4+Vive】学习笔记1
16.9.10 为了做房产项目,这两天开始学习Unreal Engine 4。之前一直用unity,但是视觉效果一直不满意,听说虚幻4的效果更好,就来试一试水。 1.安装UE4 参考资料一: htt
庞小明
2018/03/07
1K0
数字人+AI换脸简单实现虚拟制片
数字人(Digital Human / Meta Human),是运用数字技术创造出来的、与人类形象接近的数字化人物形象。数字人可简单的分为 2D 数字人和 3D 数字人。本文使用的数字人是通过 MetaHuman Creator 制作工具生成的 3D 数字人。3D 数字人的驱动方式可简单的分为真人驱动和模型驱动。本文使用的驱动方式为真人驱动。
政采云前端团队
2023/10/27
1.2K0
数字人+AI换脸简单实现虚拟制片
干货 | UE4编辑器如何生成和共享插件
和其他大型IDE(集成开发环境)和编辑器一样,UE4的编辑器也支持插件开发,从而扩展编辑器的功能,提升开发的效率。
Jean
2020/09/17
3.7K0
UE4 中通过单例类实现全局数据管理
单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
孤舟掠影
2022/11/16
1.8K0
来自次世代的暴击:虚幻引擎5首亮相,游戏实时渲染媲美影视级作品
虚幻引擎(Unreal Engine)是一款由 Epic Games 开发的游戏引擎。该引擎主要是为了开发第一人称射击游戏而设计,但现在已经被成功地应用于开发潜行类游戏、格斗游戏、角色扮演游戏等多种不同类型的游戏。
机器之心
2020/05/19
1.6K0
来自次世代的暴击:虚幻引擎5首亮相,游戏实时渲染媲美影视级作品
相关推荐
UE5 创建Level并实现Level Streaming(新手向)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档