This is good to know. I can play around with these settings.
Itās just weird because prior to making those original frame rate dependency changes you all recommended I wasnt having this issue. After I added the āleftover frameā logic and the batchupdating logic this issue started showing up.
Is it only happening when some have reached the end and been removed? When you remove an instance from an ISM the indexes all change from that index on - rather than remove the instance in line 108 change it move Z to -500,000 or something to test
I had this thought earlier that maybe my index alignment lines were having issues syncing between these arrays: ISMComponentTransforms, the actual ISM component itself, InstanceDataArray, and RemainingDeltaTimeArray, but these instances are freezing prior to any instance reaching the goal point. Iāll try your recommendation and see
I think my logic to align all indexes across the 4 arrays is right, but maybe you can find a flaw in it.
My end goal was to pool instances and not delete them anyways so this is a good road to travel down
@RecourseDesign
UPDATE: So I now keep all information and donāt remove any instances and Iām still seeing instances sticking before the first instance arrives at the goal.
The other thing that Iām wondering is in this stress test im basically creating 2000 instances in 30 seconds. I wonder if the addinstance function is trampling over instance data somehow.
I wouldnāt have thought add instances would interfere with existing indexes, and your code for adjusting the indexes looks solid - but good to remove it from the equation anyway.
Maybe a good way to visualize whatās going on is to add 3 per-instance custom floats to the ISMCs and make a material that uses them as the color - then plug in the normalized Direction?
AddInstance does trigger a navigation update, maybe that is the also causing some performance drops?
if (bNavigationRelevant && IsRegistered())
{
// If its the first instance, register the component to the navigation system
// since it was skipped because IsNavigationRelevant() requires at least one instance.
if (GetInstanceCount() == 1)
{
FNavigationSystem::RegisterComponent(*this);
}
if (SupportsPartialNavigationUpdate())
{
PartialNavigationUpdate(InstanceIndex);
}
else
{
FullNavigationUpdate();
}
}
another optimization would be to add the instances in bulk.
Itās not that important in the larger scope of things. I was hoping for an easier way to get many instances. A simple function call from a lib can do the same (as the function just loops over the instances anyway)
void UISMFunctionLibrary::GetTransforms(UInstancedStaticMeshComponent* ISM, int StartIndex, int EndIndex, TArray<FTransform> &out)
{
out.Empty();
for (int i = StartIndex; i < EndIndex; i++) {
if (ISM->PerInstanceSMData.IsValidIndex(i)) {
out.Add(FTransform(ISM->PerInstanceSMData[i].Transform));
}
}
}
I believe the new problem may be due to the next waypoint only being set in the partial update branch. While the tests you are doing for that branch might look like this shouldnāt be possible, those tests are inconsistent with the outer if (DirectionLength > KINDA_SMALL_NUMBER), and a full step ((Step.SizeSquared() < DirectionLength * DirectionLength)) may bring us within KINDA_SMALL_NUMBER, where it will then be stuck forever.
Side note: You already calculated the direction magnitude exactly, so the SizeSquared() call can be removed and the test replaced with (MaxStepSize < DirectionLength).
As to fixing, you could move the next waypoint setting code after the branch (and wrap in an appropriate distance check), or perhaps easier would be to make the test conditions consistent, by changing if (Step.SizeSquared() < DirectionLength * DirectionLength) to if (DirectionLength - MaxStepSize > KINDA_SMALL_NUMBER).
Alright, Iām going to close out this discussion! Thank you so much to everyone that took the time to contribute. Much appreciated. You guys really got me out of a frustrating bind. Iām going to continue work on some of the other optimization ideas you had throughout the chain
You can call it a visual check, I ran no tests. That said, where the amount of problematic code allows (as was the case here) I do ārunā the code in a kind of virtual machine, in my head
While new to Unreal and not a game dev, I have been programming for many years now, and logic errors like these are common; so you get good at looking for edge cases.