Unreal 加载流程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unreal 加载流程相关的知识,希望对你有一定的参考价值。
参考技术A Launch模块的Launch.cpp里GuardedMain为通常意义的Main函数,这里有游戏循环;在这个函数里,首先调用GEngineLoop.PreInit(),这个函数完成所有底层模块和自定义模块以及插件的加载(这些模块被定义为早期加载);
然后调用GEngineLoop.Init(),这里生成了 Engine 实例,调用engine实例的Init()方法,然后加载了晚期模块和插件,然后又调用Start()方法;
在engine.Init()方法内部主要工作:创建 GameInstance、GameViewportClient、LocalPlayer 实例;
在engine.Start()方法内部主要工作:调用LoadMap()方法;
在engine.LoadMap()方法内部主要工作:
1、加载map包,生成UWorld,包括level、actor等;
2、调用UWorld的一些方法,如InitWorld(),这个方法配置物理、AI、声音等;还有SetGameMode()方法,这个方法生成了 GameMode ;
3、加载始终要加载的子level;
4、调用world.InitializeActorsForPlay()方法,主要工作:
①、注册所有actor的component,并且,如果component是primitivecomponent类型,还会创建FprimitiveSceneProxy对象,该对象属于FScene(UWorld在渲染线程里的对应版本);
②、调用gameMode.InitGame(),生成 GameSession 对象;
③、循环调用所有level的RouteActorInitialize()方法,这里完成所有actor的初始化,其中GameMode也属于actor,因此会GameMode也会得到初始化,这时候会产生GameState对象;
5、产生player;上文提到的 LocalPlayer 是引擎模块的,对应的在游戏模块里为 APlayerController ,这个过程产生playercontroller,并且产生spawn;
6、调用world.BeginPlay()方法;
Unreal Engine 4 —— 异步加载关卡的实现方法及思考
这篇文章介绍了在ue4中实现异步加载关卡的方法,以及我对应的思考。
背景
在很多游戏中都有用到关卡的异步加载,关卡的异步加载指的是在游戏的某个阶段,使用多线程的方法进行新关卡对应的内容加载。从而能够免去直接的Loading阶段,提升游戏体验的效果。
目前这种方法被广泛运用于各种游戏,例如在游戏战神Ⅲ中,主角有时会走过一段长长的山道,在此时实际上游戏就已经在开始加载下一个关卡了(当主角走出山道时如果还没有加载完,则会显示Loading界面);又例如在游戏暗黑血统Ⅱ中,主角解开谜题从一个房间进入下一个房间时,往往会有一段比较长时间的推门动作,此时也是在进行对应关卡的加载……
Transition Map与异步加载关卡的异同
有人可能会将Transition map和异步加载关卡混为一谈,但实际上这两者是不一样的。异步加载关卡指的是在当前的主关卡中,使用其他线程进行内容的加载。而Transition Map指的是在需要进行加载时,给玩家一个几乎瞬间就能加载完的关卡,这个关卡可能含有一些小游戏或者训练内容。
说句题外话,这个东西在1995年被Namco申请了专利O__O ” US Patent 5,718,632,好在这项专利在2015年已经过期了……读者如果有兴趣可以阅读对应的资料,传送门。
在UE4中的实现
以下的代码是我在整理以前的代码的时候翻出来的,参考来源忘了。如果读者看到之后能给出来源我将不胜感激……
.h文件
[代码]:
1 |
DECL<a href= "http://www.52vr.com/armr/" style= "font-weight: bold;color: ;" target= "_blank" >AR</a>E_DYNAMIC_DELEGATE(FOnPackageLoaded); |
2 |
3 |
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject" ), Category = "TransitionLevel" ) |
4 |
static bool LoadLevelAsync( const FString& InName, TArray<fstring> Packages, FOnPackageLoaded OnPackageLoaded);</fstring> |
.cpp文件
[代码]:
01 |
bool UMainFunctionLibrary::LoadLevelAsync( const FString& InName, TArray<fstring> Packages, FOnPackageLoaded OnPackageLoaded) |
02 |
{ |
03 |
FTimerHandle* TimerHandle = nullptr; |
04 |
05 |
LoadPackageAsync(InName, FLoadPackageAsyncDelegate::CreateLambda([=]( const FName& PackageName, UPackage* LoadedPackage, EAsyncLoadingResult::Type Result) { |
06 |
OnPackageLoaded.ExecuteIfBound(); }), |
07 |
0, PKG_ContainsMap); |
08 |
09 |
return true ; |
10 |
}</fstring> |
代码应该比较好阅读……这里就不再赘述了。比较推荐的方法是先载入对应的子关卡和子资源,然后进行Open Level/Travel Level…方法。
对应思考
在我进行对应的实验过程中,发现在某些情况下还是出现瞬间的Hitch情况,帧率依然不稳定。
此时的原因是由于在进行Load Map的过程中存在着大量的I/O,如果出现单个资源文件太大(例如极高分辨率的贴图等)的情况下,则会出现很严重的Hitch。
因此可以考虑将一些重要的资源分解为其他较小的资源,从而进行异步读取,这可能会是一个不错的处理方法。
<全文完>
作者:谁允许你直视本大叔的
本文转自:52VR.com Unreal Engine 4 http://www.52vr.com/article-881-1.html
以上是关于Unreal 加载流程的主要内容,如果未能解决你的问题,请参考以下文章
Unreal Engine 4 蓝图完全学习教程—— 循环ForLoop
[图形学] Real Shading in Unreal Engine 4