[4.20] Hierarchical Instanced Static Mesh crash in many ways if used in C++

This happens for me now in 4.22.

Same error message as above except now it’s Line: 1259

Crashes every time I save my actor containing a HISMC if it has a static mesh set. If I remove it, I can compile, if I then re-add another one and compile, it crashes again.

It happened in another of my projects with an entirely different approach and it’s happening now again in this one. There’s something very unstable with HISMCs…

Here’s the code that I use to update a grid of instances when I change the number of tiles. This compiles. It crashes when UpdateGridVisuals() is executed from OnConstruction, but if UpdateGridVisuals() is BlueprintCallable and called from BPs from the editor, it works.

void AGridManager::UpdateGridVisuals()
{
	if (TilesTotal <= 0)
		return;

	if (!GridVisualizer) 
	{
		TArray<UActorComponent*> HISMCs = GetComponentsByTag(UHierarchicalInstancedStaticMeshComponent::StaticClass(), FName("Grid Visualizer"));
		
		if (HISMCs.Num() > 0)
			GridVisualizer = Cast<UHierarchicalInstancedStaticMeshComponent>(HISMCs[0]);
	}

	if (!GridVisualizer)
		return;

	GridVisualizer->ClearInstances();

	for (int Index = 0; Index < TilesTotal; Index++)
	{
		FTransform InstanceTransform = FTransform(FRotator::ZeroRotator, TileIndexToCoordinate(Index), TileSize / 100.0f);
		GridVisualizer->AddInstance(InstanceTransform);
	}
}

void AGridManager::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);

	UpdateGridVisuals();
}

I’ve contacted support about my kind of this problem, and this is what I’ve got:

Actually the problem is when you are
calling AddInstance(). Every time you
call this function, a Build Tree is
called to run asynchronously. So when
you are copying and pasting your HISM,
it is creating 9 Build Trees to run
asynchronously at the same time, which
is highly inefficient. To circumvent
this you would set
HISMComponent->bAutoRebuildTreeOnInstanceChanges
to false before the loop then set it
back to true after the loop and call
HISMComponent->BuildTreeIfOutdated(true,
true);

This works, but not in all cases, so not sure is it will help you.
Try and reply please…

Thank you.

I tried it now, and also tried a lot of other variations, like disabling AutoRebuildTree and doing BuildTreeIfOutdated(false,true) after every AddInstance, but nothing seems to work.

It no longer crashes, but ClearInstances() no longer removes the instances in the scene, and it failed to ever add any new instances to the scene.

I have this problem as well. I played with the amount of instances you can spawn. It turns out everything works fine if I only spawn three or less new Instances, it also does not happen if you don’t clear the instances. But only three instances and not clearing them is not really the point of HISMC’s.

Im making generation in editor using PostEditChangeProperty, and Im not using ClearInstances anymore.

Im calculate instances number delta and add/remove them accordingly.

void UpdateInstances(TArray<FTransform>& Transforms)
{
	HISMComponent->bAutoRebuildTreeOnInstanceChanges = false;

	int32 InstCountDelta = Transforms.Num() - HISMComponent->GetInstanceCount();

	if (InstCountDelta > 0)
	{
		for (int32 i = 0; i < InstCountDelta; i++)
			HISMComponent->AddInstance(FTransform());
	}
	else if (InstCountDelta < 0)
	{
		InstCountDelta = FMath::Abs(InstCountDelta);

		for (int32 i = 0; i < InstCountDelta; i++)
			HISMComponent->RemoveInstance(HISMComponent->GetInstanceCount() - 1);
	}

	for (int32 i = 0; i < Transforms.Num(); i++)
		HISMComponent->UpdateInstanceTransform(i, Transforms[i], false);

	HISMComponent->bAutoRebuildTreeOnInstanceChanges = true;
	HISMComponent->BuildTreeIfOutdated(true, true);
	HISMComponent->Modify();
}

It works well if Im setting new values directly, but sometimes its crashes if Im using mouse drag to change value. And its crashing every time when trying to copy/paste that actor.

Well, Im sure Im doing something in wrong way ))

All of thus will not cras with simple ISM components, but HISM component is more useful, especially with lods for mobile.

Had this issue. Here is how to resolve it.

  1. Set bAutoRebuildTreeOnInstanceChanges to false for your HISM components.
  2. Call BuildTreeIfOutdated(true,true); On your HISM component AFTER you finish adding all instances. This will force an update. Manually controlling it prevents a race condition.

this not working in all cases.
see my post Apr 09 '19 at 4:33 PM

So 3.5 years later, do we have a definitive reason for this crash and how to fix it? I’ve implemented the manual setting of bAutoRebuildTreeOnInstancesChanges but I still get a crash when I create a Blueprint based on a component that modifies an HISM in code.