Made my class HISM_Cubes that inherit from HierarchicalInstancedStaticMeshComponent.
Im trying to make it stop when it arrives closer to the Destination, and then 4 seconds later make remove the instance (and its struct). The struct is stored in an array, thats where i store the data related to the cube, like Speed, and other things.
Though so far its super buggy and i cant understand exactly why.
Im pretty sure im doing it all correctly as i worked in similar stuff in the past.
But here, it has been a full day of work stuck on this.
It doesnt help that the HISM is super tricky to remove, because when it removes it does so by swapping the indexes. Which is a PITA sometimes.
So if i remove instance 5 of 10 instances, it will send instance 5 to 10 and instance 10 to 5, and then remove the last index instance.
Could you tell me what im doing wrong here or if there is a better simpler way of doing this?
On the DestroyCube():
The way i remove it is by passing the Struct. Then get the instance to remove. Make sure the Last struct in the array is updated with that instance now, because im using RemoveSingleSwap.
So far it seems to be able to sometimes remove the instances, but at times it “forgets/skips” to remove an index of the array cubeStruct_Arr.
Do the same for the instance (im swapping the transforms, and then remove the last).
Full code here:
#include "HISM_Cubes.h"
UHISM_Cubes::UHISM_Cubes() {
PrimaryComponentTick.bCanEverTick = true;
}
void UHISM_Cubes::MoveCubes(float DeltaTime) {
for (int32 Index = cubeStruct_Arr.Num() - 1; Index >= 0; --Index)
{
Fcube2& cubeStruct = cubeStruct_Arr[Index];
if (cubeStruct.bMarkedForRemoval)
continue;
int32 InstanceIndex = cubeStruct.instance;
FTransform TCur;
GetInstanceTransform(InstanceIndex, TCur, true);
FVector NewLocation = FMath::VInterpConstantTo(TCur.GetLocation(), Destination, DeltaTime, cubeStruct.speed);
TCur.SetTranslation(NewLocation);
UpdateInstanceTransform(InstanceIndex, TCur, true);
if (TCur.GetLocation().Equals(Destination, 100.f)) {
cubeStruct.bMarkedForRemoval = true;
FTimerHandle TimerDestroy;
GetWorld()->GetTimerManager().SetTimer(TimerDestroy, [this, &cubeStruct]() {
DestroyCube(cubeStruct);
}, 4.f, false);
return;
}
}
}
void UHISM_Cubes::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
MoveCubes(DeltaTime);
MarkRenderStateDirty();
}
void UHISM_Cubes::DestroyCube(UPARAM(ref) Fcube2& cubeStruct) {
if (cubeStruct_Arr.Num() < 2) {
cubeStruct_Arr.Empty();
ClearInstances();
return;
}
int32 LastcubeIndex = cubeStruct_Arr.Num() - 1;
int32 LastInstanceIndex = GetInstanceCount() - 1;
Fcube2* Lastcube = &cubeStruct_Arr[LastcubeIndex];
Lastcube->instance = cubeStruct.instance;
FTransform T;
GetInstanceTransform(LastInstanceIndex, T, true);
UpdateInstanceTransform(cubeStruct.instance, T, true);
RemoveInstance(LastInstanceIndex);
cubeStruct_Arr.RemoveSingleSwap(cubeStruct);
}