上一篇按屏幕占比裁剪局部光动态阴影记的是同一个密集城市街道场景里,针对光的那一刀。这篇记另一条杠杆:那个场景里 30,518 个独立 StaticMeshComponent 直接推高的 draw-call 体量。我写了个编辑器工具把同 mesh 的散摆静物折成 HISM,全图跑通一次把 21,483 个 SMC 合进了 494 个 HISM。这篇讲为什么要合、怎么用、以及一路上崩过的几次和绕不开的坑。
一个密集城市街道场景抓的 trace 里,我碰到一个不太常见的瓶颈形态:GameThread / RenderThread / RHIThread 三条线并列卡住,各约 88 ms,彼此在 ±9 ms 内;GPU 只忙 53 ms,有约 36 ms 余量。这篇记一下我针对其中一条杠杆——局部光动态阴影——做的运行时裁剪,包括为什么这么做、实现上几个绕不开的点,以及关掉/打开 CVar 的 A/B 数据。
同一个 trace 里针对另一条杠杆(30k 散摆静物的 draw-call)的处理,见把近场散摆静物合成 HISM 削 draw-call。两条线一起压,帧时才真正掉得下来。
适用引擎:UE 5.4。平台以 Windows(dev/editor)为主,主机同理。
这是一份通用操作方法论,不针对某一次具体分析。单次分析的原始数据建议另存成一份带日期的记录,别和方法论混在一起。文中路径/类名均已脱敏,技术细节原样保留。
内存排查有两套互补工具,各有强项。我的经验是两套一起用、相互印证——单看任何一套都容易把「换血」误判成「泄漏」。
| 工具 | 强项 | 弱项 |
|---|---|---|
| memreport | 快、离线可读、给出各类对象/贴图/RT 的绝对占用,能判断「池子总量是否封顶」 | 只是快照,看不到分配来源/调用栈 |
| Unreal Insights 内存 trace | 逐条分配、时间轴、按 A/B/C 时间点筛「存活增长」、可到调用栈 | 文件巨大;调用栈需额外开启 + 配符号;区分不了「池内换血」和「真泄漏」 |
这篇整理一个 ARPG 项目(PS5 主机 + Windows 开发,UE5.4 Chaos 后端)在 DefaultEngine.ini 里对物理的全套配置——不是逐字段翻译文档,而是把**「为什么这么调」和「踩过的坑」**写清楚,下次遇到「ragdoll 飘」「瓶子落地慢」「ragdoll 一接触就嗖飞」这类问题能直接对照排查。
1. 核心物理参数 [/Script/Engine.PhysicsSettings]
1.1 重力与运动学基础
| 配置项 | 推荐值 | 说明 |
|---|---|---|
DefaultGravityZ |
-980.0 |
默认重力(cm/s²,向下),相当于地球 1g |
DefaultTerminalVelocity |
4000.0 |
自由落体封顶,防止数值爆炸 |
DefaultFluidFriction |
0.3 |
水 / 流体默认摩擦 |
MaxAngularVelocity |
7200.0 |
单刚体最大角速度(度/秒)。从默认 3600(10 rev/s)抬到 7200(20 rev/s),让 ragdoll 被击中时保留更多旋转动量 |
MaxDepenetrationVelocity |
750.0 |
穿透解算时的最大反推速度(cm/s)。不能设为 0(无限反推)——会把穿透刚体瞬间弹飞,典型表现是 ragdoll 一接触就「嗖」飞出场景。500 是稳妥起点,为改善 ragdoll 落地「软陷」可放到 750,仍远离失效域 |
BounceThresholdVelocity |
50.0 |
相对速度低于此阈值时不计入回弹。从 200(2m/s)降到 50(0.5m/s),让 ragdoll 落地的小冲击能正常传递 |
FrictionCombineMode |
Average |
两物体摩擦取均值 |
RestitutionCombineMode |
Average |
两物体回弹取均值 |
继前一篇 Significance 预算与布娃娃 / PhysicsControl 的冲突修复 之后,我们在角色基类上加了一层「离屏即 suspend PhysicsAsset / Collision」的优化(ApplyPhysicsVisibilitySuspension),通过缓存「是否处于战斗」状态把战斗中的敌人豁免,让 weapon trace / AOE 仍能命中离屏目标。
这是一份把 Unreal Insights trace 当成工程数据来读的指南。重点不是"怎么打开 Insights",而是抓到一份 trace 之后,怎么从里头逐层读出可执行的优化结论——以及一路上的坑。文中所有数据示例均来自一个 UE 5.4 的 ARPG 项目在 Win64 Development / Test 构建下的实测,已脱敏。
1. 为什么需要"方法论",而不是只看 Insights GUI
Insights GUI 直观,但有两个固有问题:
ARPG 战斗里经常会同时存在十几到几十个敌人,常见的优化做法是引入 Significance/Budget 系统:按距离、可见性给角色分桶(bucket),根据档位降低 tick 频率甚至关闭 PhysicsControl。这套系统在常态下表现良好,但只要扩大 Physics Control 被关闭的阈值范围,就会暴露出两个典型现象——它们来自同一个根因:Significance 不知道角色当下是不是 ragdoll。
1. 两个现象
| # | 现象 | 触发场景 | 关闭 Significance 后 |
|---|---|---|---|
| 1 | 远处敌人一帧布娃娃、一帧 T-Pose 反复切换 | 敌人数量多、布娃娃状态(击飞 / 击倒 / 死亡) | 消失 |
| 2 | 敌人缓慢"升天" | 击飞类技能(如 GA_KnockoutFly)的后半段(约 0.4–0.8s) |
消失 |
本文是 Gameplay Targeting System 系列 的第五篇,整理实际开发中怎么把这套系统跑得稳。
1. 新增使用场景的标准流程
1.1 给新角色加近战锁敌
- 挂组件:C++ 角色里在构造或
BeginPlay加UMeleeTargetingComponent;纯蓝图角色直接挂BP_MeleeTargetingComponent。 - 建 Preset:以现有的玩家近战 Preset 为模板复制,按角色调整(半径、过滤条件等)。命名
DA_TargetingPreset_<角色>_MeleeTarget。 - 绑定:组件的 Details 里把
Targeting Preset Find Target Actors设到新 Preset。 - 额外角度过滤(可选):项目里通常会在组件中再做一道前向夹角过滤(
FilteringTargetsByForwardAngle),蓝图可调用对应函数。