In UE5.7, calling UpdateInstanceTransform on InstanceStaticMesh 10,000 times in a C loop takes 50-100 times longer than in UE5.1. The performance of UpdateInstanceTransform is very poor.
Testing found that if all objects in collisions are set to ignore responses and collision is enabled only for queries, the performance is very good.
In UE5.1, calling UpdateInstanceTransform on InstanceStaticMesh 10,000 times in a C loop performs well. This is true even when queries and physics are enabled and all object responses are set to block.
UE5.7
Collision Presets:BlockAllDynamic
C++ UpdateInstanceTransform :10000
Time:3.43s
#include "ActorInst.h"
#include "Components/InstancedStaticMeshComponent.h"
AActorInst::AActorInst()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
MeshComp = CreateDefaultSubobject<UInstancedStaticMeshComponent>(TEXT("Mesh"));
}
void AActorInst::BeginPlay()
{
MeshComp->SetStaticMesh(Mesh);
Super::BeginPlay();
int index = 0;
for (int x = 0; x < 21; x++) {
for (int y = 0; y < 21; y++) {
for (int z = 0; z < 21; z++) {
FTransform tr;
tr.SetRotation(FQuat::MakeFromRotator(FRotator::ZeroRotator));
tr.SetScale3D(FVector(1,1,1));
tr.SetLocation(FVector(x * size, y * size, z * size));
transforms.Init(tr,index);
MeshComp->AddInstance(tr,false);
index++;
}
}
}
}
void AActorInst::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
int index = 0;
for (int x = 0; x < 21; x++) {
for (int y = 0; y < 21; y++) {
for (int z = 0; z < 21; z++) {
FTransform tr;
tr.SetRotation(FQuat::MakeFromRotator(FRotator::ZeroRotator));
tr.SetScale3D(FVector(1, 1, 1));
tr.SetLocation(FVector(x * size + FMath::RandRange(0, 99), y * size + FMath::RandRange(0, 99), z * size+ FMath::RandRange(0, 99)));
if (transforms.IsValidIndex(index)) {
transforms[index] = tr;
}
index++;
}
}
}
MeshComp->BatchUpdateInstancesTransforms(0, transforms);
}
It updates the whole instance mesh matrix transform via an array instead of per index