大量AI敌人造成巨大CPU消耗

在示例工程中创建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敌人

您好,对于大量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]

从图片上看,这里的wait应该是在EndPhysics阶段,游戏线程会进行一次阻塞等待,保证在进入下一帧或下一Tick Group之前所有FPhysicsSolverAdvanceTask以及相关的物理任务执行完毕。