Unreal Engine 大象无形学习笔记(第二部分:虚幻引擎浅析)
Q1. 虚幻引擎的Main函数在哪?
LaunchWindows.cpp 中找到 WinMain。
Q2. 虚幻引擎为什么要引入模块机制?
编辑器模式、发布模式要单独配置非常麻烦。
工具:Unreal Build Tool
包含大模块:Runtime、Development、Editor、Plugin
每个模块包含:Public、Private文件夹,.build.cs文件
作用域:只有XXXX_API宏暴露的类和成员才能被其他模块访问
Q3. 如何创建自定义模块?
1. 创建模块文件夹结构;
2. 创建模块构建文件.build.cs;
3. 创建模块头文件与实现文件;
4. 创建模块预编译头文件PrivatePCH.h;
5. 创建模块的C++声明和定义。
详细步骤见书P82
Q4.模块的加载顺序?
1)Platform File Module 读取文件
2)FEngineLoop::PreInit->LoadCoreModules 加载核心模块
3)加载 CoreUObject
4)FEngineLoop::LoadPreInitModules
5)加载 Engine
6)加载 Renderer
7)加载 AnimGraphRuntime
8)加载平台相关模块(D3D、OpenGL、StartupCoreModules、Core、Networking、UMG、MessageLog)
9)启用的插件对应模块
10)TaskGraph、ProfilerService
Q5. UE大概有哪些模块?
Documentation | WorkspaceMenuStructure | MainFrame | GammaUI | OutputLog |
SourceControl | TextureCompressor | MeshUtilities | MovieSceneTools | ModuleUI |
Toolbox | ClassViewer | ContentBrowser | AssetTools | GraphEditor |
KismetCompiler | Kismet | Persona | LevelEditor | MainFrame |
PropertyEditor | EditorStyle | PackagesDialog | AssetRegistry | DetailCustomizations |
ComponentVisualizers | Layers | AutomationWindow | AutomationController | DeviceManager |
ProfilerClient | SessionFrontend | ProjectLauncher | SettingsEditor | EditorSettingsViewer |
ProjectSettingsViewer | Blutility | OnlineBlueprintSupport | XmlParser | UserFeedback |
GameplayTagsEditor | UndoHistory | DeviceProfileEditor | SourceCodeAccess | BehaviorTreeEditor |
HardwareTargetin | LocalizationDashboard | ReferenceViewer | TreeMap | SizeMap |
MergeActors |
Q6. 什么是UBT和UHT?
Unreal Build Tool |
跨平台工具 职能: 1.收集阶段:收集环境变量、源代码目录、引擎目录、工程目录 2.参数解析阶段:解析命令行参数 3.实际生成阶段:生成makefile
4. 监视是否需要热加载
|
Unreal Header Tool |
编译头文件后,把UPROPERTY和UFUNCTION标记的信息获取过程记录在.generated.cpp里 加载信息:在.generated.cpp里声明宏:IMPLEMENT_CLASS(声明了静态全局变量,实现了当前类函数),利用静态全局变量初始化先于Main函数,选择先加载哪些信息 |
Q7. 引擎初始化过程?
1)PreInit
① 根据CmdLine传入参数设置路径
② 设置GLog输出设备
③ 将当前线程设置为主线程并初 始化
④ 初始化随机数系统
⑤ 初始化TaskGraph任务系统,根据当前平台核心数设置工作线程数,启动线程池
⑥ 判断启动模式(Game/Server)
⑦ LoadCoreModules->CoreUObject
⑧ 启动引擎模块、渲染模块、动画蓝图、Slate渲染模块、Slate核心模块、贴图压缩模块、地形模块
⑨ 调用 AppInit
2)Init
IProjectManager -> PostEngineInit
3)主循环
① 更新控制台变量
② 请求渲染线程更新当前帧率文字
③ 更新 App::DeltaTime
④ 更新内存分配器状态
⑤ 请求渲染线程刷新底层绘制资源
⑥ 等待Slate输入捕获完成
⑦ 调用 Gengine -> Tick
⑧ if(IsPlayingVedio) WaitVedioEnd
⑨ 更新 SlateApplication
⑩ 更新RHI
11 收集下一帧要清理的UObject对象
Q8. 怎么创建和使用线程?
1. 继承 FRunnable
2. 重载 Init、Run、Exit函数
3. 启动线程:FRunnableThread::Create();
Q9. 渲染线程怎么工作的?
启动:StartRenderingThread 全局函数
1. 创建渲染线程实例
2. FRunnableThread::Create创建渲染线程
3. 等待渲染线程准备好,从TaskGraph取出任务并执行(主要执行内容:RenderingThreadMain)
4. 注册渲染线程
5. 创建渲染线程心跳,更新线程
渲染线程 ==渲染命令=> RHI命令列表 ==取出并发送指令=> GPU
Q10. 虚幻渲染架构?
延迟渲染:场景中所有不透明物体
前向渲染:透明物体
渲染顺序:延迟光照(不透明物体) --> 深度排序(半透明物体)
Q11. 蓝图的数据结构?
UEdGraph
|-Schema 语法
FGraphContextMenuBUilder 定制右键菜单
|-Nodes
|-SubGraphes