在示例工程中创建180个AI敌人,帧率从200fps降低到60fps.Insight分析如下
用Insight 分析其中的1帧
FrameTime大概是 15.1ms
[Image Removed]
明确是AI敌人更新造成的消耗占7.9ms
[Image Removed]
包括
紫色 - UCharacterMovementComponent_TickComponent
蓝色 - USkeletalMeshComponent_TickAnimation
绿色 - USkeletalMeshComponent_CompleteParallelAnimationEvaluation
<br/>
未知消耗
[Image Removed]
<br/>
请问
1.如何优化CharacterMovementComponent和USkeletalMeshComponent相关的消耗?
2.未知消耗是否为物理计算?如何进行优化?是否可以关闭并行,直接在GameThread计算?
重现步骤
创建ThirdPerson的样例工程,修改CombatEnemySpawner.cpp
void ACombatEnemySpawner::BeginPlay()
{
Super::BeginPlay();
// should we spawn an enemy right away?
if (bShouldSpawnEnemiesImmediately)
{
// schedule the first enemy spawn
//GetWorld()->GetTimerManager().SetTimer(SpawnTimer, this, &ACombatEnemySpawner::SpawnEnemy, InitialSpawnDelay);
for (int32 i = 0; i < SpawnCount; ++i)
{
SpawnEnemy();
}
}
}
修改场景中的Spawner属性,一次性spawn出100+个AI敌人
TonyChen1
(TonyChen1)
September 25, 2025, 7:25am
3
您好,对于大量cmc组件的消耗由于tick都在主线程上,一般可以根据Significance Manager动态调整组件 Tick 间隔以减少更新频率,有的用户会使用NavMeshWalking移动模式来避免高昂的物理检测,对于远距离的AI也可以使用类似mass的机制,退化为更低LOD的表示,不用cmc而是用更简单的方式计算pathfinding,5.6中的下一代移动组件mover将移动的任务搬到了异步,对于要优化移动开销多了一种选择。
animation这部分需要针对具体细节进一步分析,一般建议启用URO、降低骨骼和动画复杂度等方式
对于未知消耗一般建议勾选NamedEvents再去抓trace可以记录更多的task,如果还是没有一般可能是更底层的函数,没有被insight捕获到,不一定是物理线程,需要确定具体是哪个task再去做优化
感谢回复,考虑先用SignificanceManager降URO.
还有一个问题请教,请问这个GameThread中的wait主要是在等待什么,是否可以把一部分的事情从workthread放回GameThread.[Image Removed]
TonyChen1
(TonyChen1)
September 29, 2025, 8:37am
5
从图片上看,这里的wait应该是在EndPhysics阶段,游戏线程会进行一次阻塞等待,保证在进入下一帧或下一Tick Group之前所有FPhysicsSolverAdvanceTask以及相关的物理任务执行完毕。