《LearnUE——基础指南:上篇—3》——GamePlay架构WorldContext,GameInstance,Engine之间的关系
目录
平行世界是真实存在的吗?
1.3.1 引言
1.3.2 世界管理局(WorldContext)
1.3.3 司法天神(GameInstance)
1.3.4 上帝(Engine)
1.4 总结
平行世界是真实存在的吗?
1.3.1 引言
上一小节中提到说一个World管理多个Level,并负责它们的加载释放。那么,问题来了,在UE的世界中,真的只有一个World吗?
1.3.2 世界管理局(WorldContext)
World不是只有一种类型,比如编辑器本身就也是一个World,里面显示的游戏场景也是一个World,这两个World互相协作构成了我们的编辑体验。简单来说,UE其实是一个平行宇宙世界观。
我们先看一下World的种类:
/** Specifies the goal/source of a UWorld object */
namespace EWorldType
{enum Type{/** An untyped world, in most cases this will be the vestigial worlds of streamed in sub-levels */None,/** The game world */Game,/** A world being edited in the editor */Editor,/** A Play In Editor world */PIE,/** A preview world for an editor tool */EditorPreview,/** A preview world for a game */GamePreview,/** A minimal RPC world for a game */GameRPC,/** An editor world that was loaded but not currently being edited in the level editor */Inactive};UE_DEPRECATED(4.14, "EWorldType::Preview is deprecated. Please use either EWorldType::EditorPreview or EWorldType::GamePreview")const EWorldType::Type Preview = EWorldType::EditorPreview;
}
世界类型 | 描述 |
None | 一个无类型的世界,在大多数情况下,这将是子关卡中流的残余世界 |
Game | 游戏世界 |
Editor | 在编辑器中编辑的世界 |
PIE | 编辑器世界中的游戏世界 |
EditorPreview | 编辑器工具的预览世界 |
GamePreview | 游戏的预览世界 |
GameRPC | 游戏的最小 RPC 世界 |
Inactive | 已加载但当前未在关卡编辑器中编辑的编辑器世界 |
在World.cpp里面对每种世界类型都做了判断,其代码如下:
/** Returns whether script is executing within the editor. */
bool UWorld::IsPlayInEditor() const
{return WorldType == EWorldType::PIE;
}bool UWorld::IsPlayInPreview() const
{return FParse::Param(FCommandLine::Get(), TEXT("PIEVIACONSOLE"));
}
bool UWorld::IsPlayInMobilePreview() const
{
#if WITH_EDITORif (FPIEPreviewDeviceModule::IsRequestingPreviewDevice()|| FParse::Param(FCommandLine::Get(), TEXT("featureleveles31"))){return true;}
#endif // WITH_EDITORreturn FParse::Param(FCommandLine::Get(), TEXT("simmobile")) && !IsPlayInVulkanPreview();
}bool UWorld::IsPlayInVulkanPreview() const
{return FParse::Param(FCommandLine::Get(), TEXT("vulkan"));
}bool UWorld::IsGameWorld() const
{return WorldType == EWorldType::Game || WorldType == EWorldType::PIE || WorldType == EWorldType::GamePreview || WorldType == EWorldType::GameRPC;
}bool UWorld::IsEditorWorld() const
{return WorldType == EWorldType::Editor || WorldType == EWorldType::EditorPreview || WorldType == EWorldType::PIE;
}bool UWorld::IsPreviewWorld() const
{return WorldType == EWorldType::EditorPreview || WorldType == EWorldType::GamePreview;
}
UE用来管理和跟踪这些World的工具就是WorldContext:
FWorldContext保存着ThisCurrentWorld来指向当前的World。而当需要从一个World切换到另一个World的时候(比如说当点击播放时,就是从Preview切换到PIE),FWorldContext就用来保存切换过程信息和目标World上下文信息。所以一般在切换的时候,比如OpenLevel,也都会需要传FWorldContext的参数。一般就来说,对于独立运行的游戏,WorldContext只有唯一个。而对于编辑器模式,则是一个WorldContext给编辑器,一个WorldContext给PIE(Play In Editor)的World。一般来说我们不需要直接操作到这个类,引擎内部已经处理好各种World的协作。不仅如此,同时FWorldContext还保存着World里Level切换的上下文。
粗略的流程是UE在OpenLevel的时候, 先设置当前World的Context上的TravelURL,然后在UEngine::TickWorldTravel的时候判断TravelURL非空来真正执行Level的切换。具体的Level切换详细流程比较复杂,目前先从大局上理解整体结构。总而言之,WorldContext既负责World之间切换的上下文,也负责Level之间切换的操作信息。思考:为何Level的切换信息不放在World里?
因为UE有一个逻辑,一个World只有一个PersistentLevel(见上篇),而当我们OpenLevel一个PersistentLevel的时候,实际上引擎做的是先释放掉当前的World,然后再创建个新的World。所以如果我们把下一个Level的信息放在当前的World中,就不得不在释放当前World前又拷贝回来一遍了。
而LoadStreamLevel的时候,就只是在当前的World中载入对象了,所以其实就没有这个限制了。
思考:为何World和Level的切换要放在下一帧再执行?
首先Level的加载显然是比较慢的,需要载入Map,相应的Mesh,Material……等等。所以这个操作就必须异步化,异步的话其实就剩下两种方式,一种是先记录下来信息之后再执行;一种是命令模式立马往队列里压个命令之后再执行。注意,因为OpenLevel还要相应在主线程生成相应Actor对象,所以有些部分还是要在主线程完成的。这两种模式其实都可以达成需求,前者更加简单明了,后者相对统一。UE也是个进化过来的引擎,也并不是所有的代码都完美无缺。猜想其实也是一开始这么简单就这么做了,后来也没有特别大的改动的动力就一直这样了。引擎最终比的是生产效率的提高,确实也不是代码有多优雅。
1.3.3 司法天神(GameInstance)
WorldContexts监管着所有的World,几乎达到了权利的顶峰,那WorldContexts该由什么来进行监督呢?在UE的世界中,GameInstance里会保存着当前的WorldConext和其他整个游戏的信息。明白了GameInstance是比World更高的层次之后,我们也就能明白为何那些独立于Level的逻辑或数据要在GameInstance中存储了。
这一点其实也很好理解,但凡游戏引擎都会有一个Game的概念,不管是叫Application还是Director,它都是玩家能直接接触到的最根源的操作类。而UE的GameInstance因为继承于UObject,所以就拥有了动态创建的能力,所以我们可以通过指定GameInstanceClass来让UE创建使用我们自定义的GameInstance子类。所以不论是C++还是BP,我们通常会继承于GameInstance,然后在里面编写应用于整个游戏范围的逻辑。
1.3.4 上帝(Engine)
我们继续再往上,终于得见UE上帝——Engine:
此处UEngine分化出了两个子类:UGameEngine和UEditorEngine。众所周知,UE的编辑器也是UE用自己的引擎渲染出来的,采用的也是Slate那套UI框架。好处有很多,比如跨平台比较统一,UI框架可以复用一套控件库,Dogfood等等,此处不再细讲。所以本质上来说,UE的编辑器其实也是个游戏!我们是在编辑器这个游戏里面创造我们自己的另一个游戏。话虽如此,但比较编辑器和游戏还是有一定差别的,所以UE会在不同模式下根据编译环境而采用不同的具体Engine类,而在基类UEngine里通过一个WorldList保存了所有的World。Standalone Game:会使用UGameEngine来创建出唯一的一个GameWorld,因为也只有一个,所以为了方便起见,就直接保存了GameInstance指针。而对于编辑器来说,EditorWorld其实只是用来预览,所以并不拥有OwningGameInstance,而PlayWorld里的OwningGameInstance才是间接保存了GameInstance.目前来说,因为UE还不支持同时运行多个World(当前只能一个,但可以切换),所以GameInstance其实也是唯一的。提前说些题外话,虽然目前网络部分还没涉及到,但是当我们在Editor里进行MultiplePlayer的测试时,每一个Player Window里都是一个World。如果是DedicateServer模式,那DedicateServer也会是一个World。
最后实例化出来的UEngine实例用一个全局的GEngine变量来保存。至此,我们已经到了引擎的最根处。GEngine可以说是一切开始的地方了。翻看引擎源码,到处也可以看见从GEngine->出来的引用。
既然我们在引擎内部C++层次已经有了访问World操作Level的能力,那么在暴露出的蓝图系统里,UE为了我们的使用方便,也在Engine层次为我们提供了便利操作蓝图函数库。
UCLASS ()
class UGameplayStatics : public UBlueprintFunctionLibrary
我们在蓝图里见到的GetPlayerController、SpawActor和OpenLevel等都是来至于这个类的接口。这个类比较简单,相当于一个C++的静态类,只为蓝图暴露提供了一些静态方法。在想借鉴或者是查询某个功能的实现时,此处往往会是一个入口。
1.4 总结
从结构上而言,我们已经来到了最根源的地方。GEngine仿佛就是一棵大树的根,当我们拎起它的时候,也会带出整个游戏世界的各个对象。这些对象之间的关系如下:Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine,这些对象已经足够表达UE游戏世界的各个部分。
上篇: 《LearnUE——基础指南:上篇—2》——GamePlay架构之Level和World
总纲: LearnUE——基础指南:总纲
相关文章:
《LearnUE——基础指南:上篇—3》——GamePlay架构WorldContext,GameInstance,Engine之间的关系
目录 平行世界是真实存在的吗? 1.3.1 引言 1.3.2 世界管理局(WorldContext) 1.3.3 司法天神(GameInstance) 1.3.4 上帝(Engine) 1.4 总结 平行世界是真实存在的吗? 1.3.1 引言 …...
重大问题,Windows11出现重大BUG(开始菜单掉帧,卡顿)
重大问题,Windows11出现重大BUG 这种Windows11操作系统出现BUG已经可以说是非常常见的,但是,今天我将代表所有微软用户,解决一个关于UI设计非常不舒服的功能 关闭多平面覆盖 事情叙述问题 微软社区解决方案自己发现的解决方案解决…...
修改系统语言字体的方法及注意事项
Android修改系统语言字体 随着我们生活品质的提升,现在人们对于手机的依赖越来越高,而且对于手机的功能也有了更高的要求。其中,界面的字体对于我们视觉的体验感受非常重要。而在Android系统中,默认的字体可能并不符合我们的胃口。…...
19.考虑柔性负荷的综合能源系统日前优化调度模型
说明书 MATLAB代码:考虑柔性负荷的综合能源系统日前优化调度模型 关键词:柔性负荷 需求响应 综合需求响应 日前优化调度 综合能源系统 参考文档:《考虑用户侧柔性负荷的社区综合能源系统日前优化调度》参考柔性负荷和基础模型部分…...
Midjourney关键词分享!附输出AI绘画参考图
Midjourney 关键词是指用于 Midjourney 这个 AI 绘画工具的文本提示,可以影响生成图像的风格、内容、细节等。Midjourney 关键词有一些基本的语法规则和套用公式,也有一些常用的风格词汇和描述词汇,这里我以10张不同风格和类型的美女图为例&a…...
网络安全行业就职岗位有哪些?
网络安全作为目前最火的行业之一,它的细分方向很多。下面介绍一下网络安全主要的方向岗位有哪些,以及职责是什么? 一、安全规划与设计方向 岗位名称:系统安全需求分析师。 岗位职责:负责对目标对象需要达到的安全目标…...
数据库设计-范式
范式 范式就是数据库的构建规则,目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF&#x…...
在前端开发中,何时应该使用 jQuery,何时应该使用 Vue.js
如果您是最近才开始进入 Web 前端开发领域的开发人员,那么您可能会听说过 jQuery。jQuery 是一个小巧而功能强大的 JavaScript 库,旨在简化跨浏览器 DOM 操作、事件处理、动画效果和 AJAX 等方面的操作,可以让开发人员更轻松地开发出高质量的…...
Promise类方法
这篇主要讲一下Promise的类方法的基本使用,至于Promise的基本使用这里就不赘述了,之前也有手写过Promise、实现了Promise的核心逻辑。其实我们平时用Promise也挺多的,不过又出现了两个新的语法(ES11,ES12新增了两个&am…...
transformer and DETR
RNN 很难并行化处理 Transformer 1、Input向量x1-x4分别乘上矩阵W得到embedding向量a1-a4。 2、向量a1-a4分别乘上Wq、Wk、Wv得到不同的qi、ki、vi(i{1,2,3,4})。 3、使用q1对每个k(ki)做attention得到a1,i(i{1,2,3,4…...
数据结构(六)—— 二叉树(4)回溯
文章目录 一、题1 257 二叉树的所有路径1.1 写法11.2 写法2 一、题 1 257 二叉树的所有路径 1.1 写法1 递归回溯:回溯是递归的副产品,只要有递归就会有回溯 首先考虑深度优先搜索;而题目要求从根节点到叶子的路径,所以需要前序…...
JVM基础知识(一)
1.整体架构和组件 1.Class Loader Class Loader(类加载器)负责将.class文件加载到JVM中,并生成对应的Java类对象(Class对象)。Java中有三种类加载器: Bootstram ClassLoader:加载核心类库&…...
ASP.NET Core Web API用户身份验证
一、JWT介绍 ASP.NET Core Web API用户身份验证的方法有很多,本文只介绍JWT方法。JWT实现了服务端无状态,在分布式服务、会话一致性、单点登录等方面凸显优势,不占用服务端资源。简单来说,JWT的验证过程如下所示: &a…...
785. 快速排序
785. 快速排序 给定你一个长度为 n n n 的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n n n。 第二行包含 n n n 个整数(所有整数均在 1 ∼ 1 0 9 1 \th…...
C6678学习-IPC
文章目录 1、简介2、模块MultiProc静态设置(cfg设置)动态设置 IPCNotifyMessageQShareRegion 1、简介 IPC: Inter-Processor Communication 处理器间通信,指提供多处理器环境中的处理器之间的通信、相同处理器不同线程间的通信。包括数据传递…...
利用 Delte-Sigma ADC简化电路设计
很多时候在电路中选择合适的 ADC可以很大程度上简化前端的电路。这里我们一起来看一个电阻电桥的例子: 这里用到了一只仪表放大器和一只运算放大器,他们实际上主要完成了三个功能: 1. 抑制了 2.5V的共模信号; 2. 将-1…...
如何在 Windows 11 启用 Hyper-V
准备在本机玩一下k8s,需要先启用 Hyper-V,谁知道这一打开,没有 Hyper-V选项: 1、查看功能截图: 2、以下文件保存记事本,然后重命名为*.bat pushd "%~dp0" dir /b %SystemRoot%\servicing\Packa…...
哈希表企业应用-DNA的字符串检测
DNA的字符串检测-引言 若干年后, ikun DNA 检测部成立,专门对 这些ikun的解析检测 突然发现已经完全控制不了 因为学生已经会了 而且是太会了 所以DNA采用 以下视频测试: ikun必进曲 ikun必经曲 ikun必阶曲 如何感受到了吧!,如果你现在唱跳并且还Rap 还有打篮球 还有铁山靠 那…...
Kafka运维与监控
Kafka运维与监控 Kafka运维与监控一、简介二、运维1.安装和部署安装部署 2.优化参数配置配置文件高级配置分区和副本设置分区数量设置副本数量设置 网络参数调优传输机制设置连接数和缓冲区大小设置 消息压缩和传输设置消息压缩设置消息传输设置 磁盘设置和文件系统分区磁盘容量…...
【Redis—哨兵机制】
文章目录 概念哨兵机制如何工作的监控(如何判断主节点真的故障了)哪个哨兵进行主从故障转移?故障转移流程哨兵集群 概念 当进行主从复制时,如果主节点挂掉了,那么没有主节点来服务客户端的写操作请求了,也…...
MySQL学习笔记第七天
第07章单行函数 2. 数值函数 2.4 指数函数、对数函数 函数用法POW(x,y),POWER(X,Y)返回x的y次方EXP(X)返回e的x次方,其中e是一个常数,2.718281828459045LN(X),LOG(X)返回以e为底的X的对数,当x<0时,返…...
中级软件设计师备考---程序设计语言和法律法规知识
目录 需要掌握的程序语言特点法律法规知识---保护期限法律法规知识---知识产权人确定法律法规知识---侵权判定标准化基础知识 需要掌握的程序语言特点 Fortran语言:科学计算、执行效率高Pascal语言:为教学而开发的、表达能力强,演化出了Delp…...
Leetcode434. 字符串中的单词数
Every day a leetcode 题目来源:434. 字符串中的单词数 解法1:istringstream 我们知道,C默认通过空格(或回车)来分割字符串输入,即区分不同的字符串输入。 istringstream类用于执行C风格的串流的输入操…...
C++ cmake工程引入qt6和Quick 教程
目录标题 前言QML简介锻炼C水平 cmake修改方法方式一(qt6_add_resources)方式二 (qt_add_qml_module ) 其他相关知识为什么会有_other_files?qt_standard_project_setup() 函数qt_add_qml_module() 和 qt6_add_resources()的方式差异const QU…...
JavaEE - 网络编程
一、网络编程基础 为什么需要网络编程? 用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。 与本地打开视频文件类似,只是视频文件这个资源的来源是网络。 相比本…...
【Android车载系列】第11章 系统服务-SystemServer自定义服务
1 编写自定义系统服务 1.1 AIDL接口定义 系统源码目录/frameworks/base/core/java/android/app/下新建AIDL接口IYvanManager.aidl package android.app;/** * 目录:/frameworks/base/core/java/android/app/IYvanManager.aidl */ interface IYvanManager{String …...
Lerna
Lerna Lerna是一个优化基于gitnpm的多pagkage项目的管理工具 解决的痛点 痛点一:重复操作 多Package本地link多Package依赖安装多Package单元测试多Package代码提交多Package代码发布 痛点二:版本一致性 发布时版本一 致性发布后相互依赖版本升级 package越多,管…...
迁移学习 pytorch
迁移学习(Transfer Learning)是通过使用一个预训练模型来快速训练一个新的网络模型,通常应用于数据集较小或计算资源较少的情况下。在 PyTorch 中,由于 torchvision 库中已经内置了一些经典的预训练模型,因此我们可以通过简单的调用函数来实现迁移学习。 下面是一个基于 …...
【python】keras包:深度学习( RNN循环神经网络 Recurrent Neural Networks)
RNN循环神经网络 应用: 物体移动位置预测、股价预测、序列文本生成、语言翻译、从语句中自动识别人名、 问题总结 这类问题,都需要通过历史数据,对未来数据进行预判 序列模型 两大特点 输入(输出)元素具有顺序关系…...
vue框架快速入门
vue 1、第一个Vue程序1.1、什么是Vue程序1.2、为什么要使用MVVM1.3、Vue1.4、第一个vue程序 2、基础语法2.1、v-bind2.2、v-if, v-else2.3、v-for2.4、v-on 3、Vue表单双绑、组件3.1、什么是双向数据绑定3.2、在表单中使用双向数据绑定3.3、什么是组件 4、Axios异步…...
临淄房产信息网123/历下区百度seo
marker: 边缘:’MarkerEdgeColor’, [],(RGB 配色)填充:’MarkerFaceColor’, [](RGB 配色)转载于:https://www.cnblogs.com/mtcnn/p/9421894.html...
东营有网站/企业宣传推广方案
...
网站建设 全包 制作/太原网络推广价格
就当下的商显市场而言:不管是LED拼接屏、lcd液晶拼接屏还是DLP屏都是用户比较亲睐的大尺寸显示设备。但在这些显示设备中、很多的用户对LED拼接屏与lcd液晶拼接屏不是特别的清楚。往往认为两者是同一类显示设备。这两者间真的没有什么明显的区别吗?为此、…...
自己做的网站怎么上传到域名/如何在手机上开自己的网站
文 | 曾响铃 来源 | 科技向令说(xiangling0815) 众所周知,在经济技术全球化的今天,标准体系已经逐渐成为国际产业发展中的关键因素,谁能主导标准制定,谁就能成为信息时代全球企业竞争的优势方。 而最近&am…...
公司网站建设需要提供什么材料/百度输入法
需求是催生项目和推进项目的不竭动力。 背景: 最近,因为媳妇要做个B超检查,想着去大医院查查应该更放心,所以就把目标瞄准在A医院。早已耳闻A院一号难求万人空巷,所以把所有能接触到的机会都看了一遍,线下听…...
微信公众号采集插件wordpress/seo查询工具网站
像排序这种事情,用C/C可以写,但很麻烦,交给sort就好了,功能很强大的。1、按照多个列排序(列间空格分开):测试数据:先按照第1列排序,再第2列的命令:2011-11-20补充:必须加…...