Unreal Engine 5.5–5.8Windows 64 位

FrameDoctor 用户指南

记录场景中发生的事情,找出耗时的 CPU 工作,并检查手动修改是否有效。即使这是你的第一个 Unreal Engine 项目,也可以从这里开始。

  1. 记录场景
  2. 阅读验证数据
  3. 进行一项修改
  4. 比较运行结果
  5. 保存结果

帧就是游戏的一张画面。帧耗时是游戏生成下一帧所需的时间。耗时长的帧会让人感觉画面停顿或卡顿。FrameDoctor 会记录包含计时事件的跟踪文件,再将这些事件整理为图表和 CPU 作用域列表。

  • Capture:记录正在运行的场景。
  • Findings:阅读帧耗时,检查一项 CPU 工作。
  • Compare:测量修改前后保留下来的两个 Development 构建。
  • Runs:重新查看记录,导出验证数据。
  • Settings:保存记录配置,选择阈值。
修改由你完成。FrameDoctor 帮助你调查和测量,不会重写代码或自动修复游戏。分析在本地进行。

本指南已翻译,但文中提到的插件控件仍使用其英文名称。语言选择器切换的是本指南的语言。不熟悉的 Unreal 术语可在简明术语表中查阅。

安装并打开 FrameDoctor

FrameDoctor 支持 Windows 64 位上的 Unreal Engine 5.5、5.6、5.7 和 5.8。请选择与引擎版本匹配的插件包。

如果你从未打开过 Unreal

打开 Epic Games Launcher → Unreal Engine → Library,启动已安装的引擎。打开现有项目,或选择 Games → Blank → Blueprint,输入项目名称和文件夹,然后点击 Create。项目保存整个游戏;地图也称关卡,用于保存其中的一个场景。

从 Fab 安装

  1. 关闭 Unreal Editor。在启动器的 Fab Library 中找到 FrameDoctor,点击 Install to Engine。
  2. 选择项目使用的引擎版本,完成安装。
  3. 打开项目。进入 Edit → Plugins,搜索 FrameDoctor 并启用,按提示重启编辑器。
  4. 从编辑器主菜单打开 Tools → FrameDoctor。

安装提供的 ZIP 包

  1. 关闭编辑器,解压插件。
  2. 将其中单独的 FrameDoctor 文件夹放入项目的 Plugins 文件夹。如果没有 Plugins,请先创建。
  3. 检查下面的路径,避免多出一层 FrameDoctor/FrameDoctor 嵌套文件夹。
  4. 打开项目,在 Edit → Plugins 中启用插件,重启后打开 Tools → FrameDoctor。
YourProject/
  YourProject.uproject
  Plugins/
    FrameDoctor/
      FrameDoctor.uplugin
      Content/
      Resources/
      Source/
Unreal 要求编译模块怎么办?

已编译的插件包还包含 Binaries。只有源码的包需要匹配的 C++ 编译工具链,即使游戏使用 Blueprint 也一样。安装 Visual Studio 2022,并选择 Game development with C++ 以及引擎所需的 Windows SDK。对于纯 Blueprint 项目,可通过 Tools → New C++ Class 添加一个最小类,创建 C++ 项目目标。关闭 Unreal,在 Visual Studio 中构建项目的 Development Editor / Win64 目标,然后重新打开项目。如果编译失败,请阅读第一条构建错误,并确认引擎与插件包版本匹配。

Epic 指南:启用和安装插件。

首次记录

先使用一个场景。情景用于告诉 FrameDoctor 场景何时准备就绪、何时可以开始测量。学习操作和调查场景时,可以选择使用单独示例项目中提供的情景。

步骤 1 之前:安装与引擎版本匹配的 FrameDoctor,建议安装到引擎。下载可选示例项目(UE 5.5–5.8,Win64)并解压。此项目仅包含内容资源,需要单独安装插件,默认关联 UE 5.5。使用 UE 5.6–5.8 时,请先右键点击 FrameDoctorExample.uproject,选择 Switch Unreal Engine version,再选择你的引擎。用该引擎打开 FrameDoctorExample.uproject,并确认已启用 FrameDoctor。

  1. 打开并保存地图。在示例项目中打开地图,或选择 File → New Level 创建地图,将其保存在项目的 Content 文件夹中,然后使用 File → Save All。
  2. 开始 Play。点击编辑器工具栏中的三角形 Play 按钮。这就是 Play In Editor,简称 PIE。按 Shift + F1 释放鼠标,即可在游戏继续运行时使用编辑器。
  3. 选择 Capture。打开 Tools → FrameDoctor → Capture。保持 Use a packaged Development build 未勾选。PIE 记录的是已在 Play 中运行的地图;在 Map 字段选择另一张地图不会切换当前世界。
  4. 选择示例。在 Scenario 中搜索 BP_ExploratoryScenario。要找到该资产,可打开 Content Browser,或按 Ctrl + Space 打开 Content Drawer,然后查看 Content → FrameDoctorExample → Scenarios(/Game/FrameDoctorExample/Scenarios)。情景应在 FrameDoctor 中选择,不需要拖入关卡。
  5. 开始记录。保留 10 秒预热和 60 秒测量。阅读 Preflight,再点击 Capture running PIE。让 Play 继续运行,执行你想调查的操作。预热不计入测量结果。
  6. 阅读 Findings。记录完成后,如果尚未选中 Findings,请打开它。先阅读 Capture quality and unavailable reasons,再选择一个 CPU 作用域查看其验证数据。
第一个示例仅用于探索。其描述没有确立可复现的游戏条件。你可以检查跟踪,但在确认 A/B 效果前,应使用正确描述条件的情景和两个 Development 构建。

请让游戏一直运行到记录结束。Esc 或编辑器的 Stop 按钮可能结束 PIE,导致记录中断。如需取消 FrameDoctor 当前的任务,请使用其中的 Cancel。

选择记录内容

Capture 有两种记录目标。未勾选 Use a packaged Development build 时,记录当前 PIE 世界;勾选后,FrameDoctor 会单独启动打包后的游戏。需要可复现的修改前后测量时,请使用打包后的游戏。

Capture 控件
控件使用方法
Baseline Development executable使用 Browse 选择保留下来的构建 A。此路径与 Compare 共用。
Map 和 Scenario选择情景类。对于 Development,请提供已烘焙的地图和情景类路径。
Warmup准备就绪后,等待场景稳定的时间。不计入测量。
Measurement计入结果的时间。先从 60 秒开始。
Detailed naming for investigation包含更多具名事件。这会增加开销,A/B 两侧应保持相同设置。
Preflight开始前查看选定模式、跟踪通道和可用磁盘空间。

常规 CPU 配置使用 cpu,frame,bookmark。CPU 事件描述工作,frame 事件提供帧边界,bookmark 标记测量区间。如果已有外部记录正在运行,必须先结束它,FrameDoctor 才能开始自己的跟踪。

顺序是先准备就绪,再预热,最后测量。Ready timeout 和 Maximum trace size 在 Settings 中设置。被取消或中断的记录会连同状态一起保留,但不能作为已完成的比较基准。

Capture 页面,显示 Development 目标、地图、情景、预热、测量及 Preflight。
此图演示打包后的 Development 设置。使用单独示例项目时,请保持打包构建复选框未勾选,并使用 PIE。

阅读 CPU 验证数据

打开现有跟踪

点击 Import trace,选择已经结束记录的 .utrace 文件,等待 Findings 显示。导入前请先停止记录。如需保留比较的来源依据,请将相邻的 manifest.json 和原始运行文件与跟踪一起保留。阅读 Capture quality and unavailable reasons,检查可用的 CPU、帧和测量数据。

如果无法唯一确定一对完整的 FrameDoctor 测量开始和测量结束书签,就会将整个跟踪作为探索记录进行分析。运行清单缺失或其格式不受支持时,记录的完整性仍处于未验证状态。你可以检查可用事件,但不能将未验证数据或探索数据作为已确认的 A/B 基准。

先查看记录状态和质量。如果数据不完整或某个值显示 Unavailable,请打开 Capture quality and unavailable reasons。这表示无法确定该值,并不表示它等于零。

  1. 阅读 Game frame p95 和测量时长,将曲线与帧预算比较。
  2. 通过 Search scopes… 查找计时器名称,或通过 All threads 选择线程。线程是 CPU 上的一条工作流;GameThread 通常运行游戏逻辑。
  3. 点击作用域所在行。面板会解释 Measured(测量内容)、Interpretation(结果解读)、Next experiment(下一步实验)和 Behavior risk(行为风险)。
  4. 使用 Copy evidence 复制选定计时器、线程和区间的标识信息。使用 Open in Insights 在 Unreal Insights 中打开同一跟踪,再手动定位到该区间。

Exclusive / frame 是该作用域扣除同一线程上的子作用域后,在有效帧上的平均耗时。Calls 统计测量区间内开始的调用次数。作用域可能包含等待。仅凭名称无法确定具体资产,也无法证明某一个 Blueprint 节点的开销。

搜索有可见范围限制。表格会加载排名靠前的 250 行。搜索和线程筛选仅作用于这些已加载的行。完整的分析 JSON 保留了其他作用域的汇总数据。使用 Clear filters 可恢复表格。

不要通过叠加嵌套的包含耗时或并行线程耗时来估算帧开销。游戏帧、渲染帧和 GPU 队列上下文有不同含义。如果没有权威的 GPU 帧数值,该值将保持不可用。

Findings 中的实际帧图表、选中的 EnemyAwareness::Update 作用域及其验证数据面板。
选择作用域后,可以把测得的开销与下一步调查联系起来。图中数值为一次示例记录。

查看帧耗时图表

横轴是测量期间的时间,纵轴是以毫秒计的帧耗时。峰值越高,帧越慢。虚线预算线表示你选择的目标:16.67 ms 约等于每秒 60 帧。

  • 缩放:在绘图区上使用鼠标滚轮,或拖动下方小型概览图中的琥珀色手柄。
  • 平移:拖动概览图中的选中范围内部。图表获得键盘焦点时,可用左右方向键移动可见范围。
  • 检查:在绘图区上移动指针。读数会显示时间或聚合桶、样本数,以及可用的最短和最长耗时。
  • 重置:点击 Reset view。Home 或 Esc 也可重置当前获得焦点的图表。
缩放改变的是视图。顶部的 p95、CPU 作用域列表和验证数据仍使用整个测量区间。缩小可见范围不会按该范围重新计算这些值。

显示的时间范围较大时,多个帧可能共用一个绘图桶。请查看桶的样本数和数值范围,不要把它当作单帧。缺失帧数据的地方仍显示为空缺。

放大的帧耗时图表,包含概览手柄、悬停桶读数,以及保持不变的全程测量指标。
概览标出当前可见的部分;说明文字会指出哪些数值仍描述整个记录。

准备两个 Development 构建

Development 构建是启用开发功能、可在编辑器之外运行的打包游戏。Baseline A 是原始构建,Candidate B 包含一项预期修改。请将每个完整构建分别保存在独立文件夹中。

  1. 保存地图和可用于比较的情景。在项目中启用 FrameDoctor。
  2. 打开 Edit → Project Settings → Packaging。将地图加入 List of maps to include in a packaged build。还要确保情景 Blueprint 会被烘焙:从已包含的内容中保留对它的硬引用,或将其文件夹加入 Additional Asset Directories to Cook。
  3. 在编辑器的 Platforms → Windows 打包控件中,将构建配置选为 Development,然后打包项目。不同引擎版本的菜单分组可能不同。将完整输出保存为构建 A。
  4. 手动进行一项要测试的修改。保存后,将构建 B 打包到另一个目录。保持场景、输入、摄像机、NPC 和记录设置一致。
  5. 在 Capture 中勾选 Use a packaged Development build。浏览并选择 A 的可执行文件,再选择地图并输入情景的生成类路径。
Map: /Game/Maps/TestMap
Scenario: /Game/Scenarios/BP_TestScenario.BP_TestScenario_C
Executable: BuildA/Windows/YourProject/Binaries/Win64/YourProject.exe

请使用你自己的资产名称。/Game 是 Unreal 中的项目 Content 文件夹,不是 Windows 盘符。生成的 Blueprint 类以 _C 结尾。应保留包含内容的整个打包文件夹,仅复制可执行文件是不够的。

Preflight 检查请求的设置。外部构建是否包含对应地图和情景,要靠实际加载来确认。记录功能面向开发配置;Shipping 和 Test 构建无法进行 FrameDoctor 记录。

Epic 指南:打包 Unreal 项目。

检查修改是否有效

  1. 按上述步骤准备 A 和 B。在 Compare 中展开 New Development comparison。
  2. 选择 Baseline Development executable 和 Candidate Development executable。在 Intended change 中准确说明修改了什么。
  3. 启动前选择 Primary metric:p95GameFrame 用于较慢的帧,meanGameFrame 用于平均帧耗时,p99GameFrame 用于更慢的尾部帧。
  4. 先从 5 对、10 秒预热和 60 秒测量开始。对于预期的构建修改,通常只保留 gameBuildId 为允许的差异。匹配分辨率、画质设置、VSync、帧率上限、情景和计测设置。
  5. 点击 Launch paired Development series。FrameDoctor 按 AB/BA 交替顺序运行保留的构建。系列结束前,请勿更改两个构建文件夹。
  6. 阅读判定及其原因、配对差值、噪声、阈值和每对原始数据。通过 Open HTML report 或 Open report folder 打开保存的结果。
比较判定的含义
判定下一步
Improved选定帧耗时指标持续下降,超过确认阈值。请另外检查游戏行为是否正确。
Regressed选定指标持续上升,超过阈值。请调查或撤销修改。
Inconclusive效果过小、不一致,或缺少足够的有效数据。这不代表结果相等或没有效果。
InvalidComparison这些运行无法支持有效比较。请阅读不匹配或数据缺失的原因,先修正问题。

确认效果需要可比较的条件,以及至少 5 个完整配对,每次运行测量 30 秒且包含 300 个完整有效帧。较短记录可用于探索。示例探索情景无法确认效果。

毫秒值越低越好。配对差值是每对 B − A 差值的中位数,可能不同于屏幕上两个中位数相减的结果。效果必须超过绝对阈值、相对阈值和估计噪声三者中的最大值,且至少 80% 的配对方向一致。默认值为 0.5 ms 和 5%。这些检查有助于判断稳定性,但不能单独确定原因。

如需重新查看已完成的系列,使用 Import series and export report 并选择其 series.json。允许的差异不能豁免计测设置或计算方法的不匹配。

实际的五对比较,显示判定、各次运行、配对差值、噪声和阈值。
查看汇总判定时,也请检查所有配对及其条件。

重新打开并分享验证数据

打开 Runs,点击 Refresh saved runs。选择一行以阅读其来源详情。双击某次运行,或点击 Open selected evidence,即可重新打开 Findings。选择系列会打开其配对报告。

默认输出位置为 <YourProject>/Saved/FrameDoctor,可在 Settings 中选择其他输出文件夹。单次运行保留原始 .utrace、清单和分析结果。系列保留 series.json、comparison.json、HTML 报告,以及指向原始运行的引用。

  1. 加载要分享的系列。
  2. 通过 Include source traces in the export 选择是否包含原始跟踪。根据情况,保持 Remove absolute paths and username from exported JSON 启用。
  3. 点击 Export paired series bundle,选择导出位置,等待完成。
  4. 检查导出的文件,然后将完整包发送给审核结果的人。
原始跟踪保留原有内容。JSON 脱敏不会清除跟踪内部的路径或消息。两个导出复选框默认都已启用。你可以不包含跟踪,以减小审核包体积;但接收者如需在移动后重新确认结果,仍需要原始有效运行数据和原始跟踪。

Promote current run to baseline 将符合条件的、已完成且可比较的运行保存到 <YourProject>/FrameDoctor/Baselines。短记录或探索记录不符合条件。在不再需要检查或重新确认前,请保留原始数据。

已保存的完成运行、原始跟踪的可用状态、导出选项和选中的原始记录。
保留可用的原始跟踪,才能让报告与实际记录保持关联。

保存重复使用的设置

配置是一组保存下来的记录和分析设置。在 Settings 中选择 Profile ID 和名称,填写各字段,再使用 Save profile。使用 Load profile 可重新打开配置 JSON 文件。如果希望随项目历史一同管理,请将配置保存在项目的 FrameDoctor/Profiles 文件夹中。

首先需要了解的设置
设置含义
Trace channels常规 CPU 和帧记录使用 cpu,frame,bookmark。
Ready timeout预热开始前,等待情景准备就绪的最长时间。
Maximum trace size单个跟踪的磁盘容量预算。超过该值的运行会失败,并保留部分数据。
Frame budget目标帧耗时,默认为 16.67 ms。
Hitch threshold将帧计为长帧的阈值,默认为 50 ms。
Absolute / relative effect threshold考虑噪声检查前所需的最小比较效果,默认为 0.5 ms 和 5%。
Output folder新记录和报告的保存位置。留空则使用默认的 Saved/FrameDoctor。

A/B 两侧应使用相同配置。开始实验前,请根据目标调整阈值。任务运行时编辑表单,不会改写该任务已记录的设置。采用尚不支持的较新格式版本的配置会以只读方式打开;请使用兼容的插件,不要手动更改其格式版本号。

Settings 页面,包含配置字段、记录限制、分析阈值和输出位置。
保存配置后,后续记录就能使用同样经过明确选择的条件。

创建可重复的情景

准备好确认修改前后效果时,请使用本节。情景需要设置并描述实际的摄像机、输入、NPC 和随机条件。可通过 Blueprint 实现其钩子;编写情景不强制要求 C++。

要在现有项目中使用单独提供的示例,请先打开示例项目,在 Content Browser 中右键点击 BP_ExploratoryScenario,选择 Asset Actions → Migrate。将你自己项目的 Content 文件夹设为目标位置,并在该项目中启用 FrameDoctor。也可以按照以下步骤创建自己的情景。

  1. 在 Content Browser 中选择 Add → Blueprint Class → All Classes。搜索 FrameDoctorScenario,在项目内容中创建 BP_TestScenario。
  2. 打开该 Blueprint,在 Overrides 菜单中实现下面的钩子。这是记录时选择的对象,不是放置在关卡中的 Actor。
  3. 编译并保存 Blueprint 和地图。在 FrameDoctor 中选择该类。打包记录时,请按准备 A 和 B中的说明,将地图和情景包含在烘焙中。
  4. 开始长时间比较前,先进行一次简短的探索记录,检查就绪判断和清理逻辑。
情景钩子
钩子Blueprint 需要完成的工作
Prepare(World)找到实际场景中的 Actor,保存将要更改的设置,设置摄像机、输入和 NPC 状态,并初始化使用的随机流。
IsReady只有在所需 Actor、资产和初始状态准备好后才返回 true。默认返回 false。仅等待固定时间不能证明已经就绪。
BeginMeasurement预热后开始受控操作。
EndMeasurement测量结束时停止该操作,也要处理操作开始后被取消的情况。
Cleanup只恢复你自己的情景所做的修改,处理部分准备完成和取消的情况。
DescribeScenario返回描述下列条件的 Frame Doctor Scenario Snapshot。
填写情景快照

在 DescribeScenario 中,将 Make Frame Doctor Scenario Snapshot 连接到返回值。如实填写这些字段:

  • ScenarioId / Revision:稳定、非空的标识和修订版本。
  • CameraRoute:实际固定视点或可复现的路径。
  • InputConditions:使用的输入,或排除玩家输入的方法。
  • NpcConditions:NPC 数量和行为;没有 NPC 时也应明确说明。
  • ParametersJson:可选的有效 JSON 对象。例如,只有实际场景符合时,才填写 {"route":"fixed","npcCount":0}。
  • SeedPolicy / RandomSeed:只有确实用该种子初始化了游戏随机性时才使用 Known;没有使用随机性时使用 NotUsed;尚未确定时使用 Unknown。
  • DeclaredNondeterminism:仍存在的变化来源,例如物理、流式加载或操作系统调度。

仅填写一个种子数字不会替你初始化游戏。条件未知时仍只能用于探索。单独示例项目中提供的 BP_ExploratoryScenario 会有意返回空描述。

不要在 Cleanup 中移除其他系统的 Actor 或记录。性能修改后,请另外检查游戏行为;计时条件相同并不代表新逻辑正确。

遇到问题时

Tools 中找不到 FrameDoctor

检查 Edit → Plugins,启用 FrameDoctor 并重启。确认插件包与引擎匹配,且 FrameDoctor.uplugin 直接位于插件文件夹内。使用源码时,请先完成 Development Editor 构建。

Capture running PIE 不可用

使用 Play 启动场景。保持打包构建复选框未勾选,选择具体的情景类,并等待其他任务结束。使用 Shift+F1 释放 PIE 鼠标后即可操作页签。

看不到示例情景

可选示例需要单独下载;插件包不包含 Blueprint 示例。打开已安装并启用 FrameDoctor 的示例项目,在 Content → FrameDoctorExample → Scenarios 下搜索 BP_ExploratoryScenario,再在 Capture 中选择其类。若使用自己的项目,请先通过 Migrate 迁移该资产。它不是关卡 Actor。

出现 Ready timeout

情景未在时限内准备就绪。请检查 IsReady 重写、实际 Actor 和资产、地图,以及烘焙后的类路径。基类返回 false。如果确实需要更长加载时间,可增加 Ready timeout,但就绪检查仍应有实际意义。

帧耗时或独占开销显示 Unavailable

帧耗时需要测量区间内的 frame 事件和完整帧。独占 CPU 开销还需要完整且一致的作用域层级。记录 cpu,frame,bookmark,让运行保持进行,并阅读保留的原因。切勿把不可用值当作零。

比较结果为 Inconclusive 或 InvalidComparison

阅读原因。检查每次运行的状态、5 个完整配对、每次运行 30 秒测量和 300 个完整帧、描述完整的情景、稳定的条件及匹配的计测设置。Inconclusive 不能证明没有效果;解释差值前应先修复有效性问题。

打包构建找不到地图或情景

在启用 FrameDoctor 的情况下打包 Development 构建。烘焙时同时包含地图和情景。使用 /Game/... 资产路径及 Blueprint 类后缀 _C。从保留的完整构建文件夹中选择可执行文件。

记录失败、停止或超出磁盘限制

阅读已保存运行的状态和原因。检查磁盘空间、写入权限、跟踪大小限制,以及是否有其他记录器正在运行。下次记录时减少事件详细程度或时长。保持 Play 运行,测量期间避免切换地图或更改画质设置。

Open in Insights 无法打开跟踪

安装对应引擎的 Unreal Insights 工具,确保原始跟踪仍然可用。FrameDoctor 打开的是同一原始文件;准确的计时器、线程和区间需要手动定位。如果引擎无法打开含非 ASCII 字符的路径,请保留原始记录,并使用简单的 ASCII 工作路径。

报告能打开,但原始跟踪缺失

导出的报告可能无需跟踪也能查看,但重新确认需要原始有效数据。请重新导出包含原始跟踪的包,或恢复完整的原始运行文件夹。JSON 脱敏不会生成缺失的跟踪。

简明术语表

Project / map(项目/地图)
游戏的工作空间/保存在其中的一个关卡或场景。
Blueprint(蓝图)
用于可视化脚本的 Unreal 资产。你通过连接节点编程,而不必编写 C++。
PIE
Play In Editor,即在 Unreal Editor 内运行游戏。
Development / Shipping
用于开发的构建/最终发布配置。打包记录应使用 Development。
Trace / .utrace(跟踪)
记录计时事件的原始文件。
Scope / timer / thread(作用域/计时器/线程)
测量的一段工作/它的名称/运行这段工作的 CPU 工作流。
ms / FPS
每帧毫秒数/每秒帧数。每帧耗时 16.67 ms 时,游戏每秒大约生成 60 帧。
Mean / p95 / p99(平均值/p95/p99)
平均帧耗时/95%/99% 的完整帧耗时不超过的值。百分位数越高,越侧重较慢的帧。
Warmup / measurement(预热/测量)
不计入结果的稳定等待时间/用于计算结果的区间。
Baseline / candidate / pair(基准/候选/配对)
原始构建/包含修改的构建/两者各运行一次后组合使用。
Noise / threshold(噪声/阈值)
重复运行之间的变化/确认效果所需的最小稳定变化。
Cook(烘焙)
Unreal 准备资产,使其能在打包游戏中运行的过程。
Manifest / profile(清单/配置)
记录保存的条件和状态/为记录选择的设置。

版本与支持

FrameDoctor 1.0.0 · Unreal Engine 5.5、5.6、5.7 和 5.8 · Windows 64 位。

寻求帮助时,请提供引擎和插件版本、使用的是 PIE 还是 Development、点击的操作、保存的状态和原因,以及预期结果。必要时可附上截图或已审查内容的验证数据包。避免分享个人路径或尚未检查的原始日志。

如发现本指南有错误或说明不清,请提交文档问题。插件支持请使用 FrameDoctor 产品页面或购买渠道上的支持联系方式。