AI optimization

Well That can slow down your character as well,
I suggest to dump the hit boxes and to work directly withba mesh bones,
it will require some more work to map all the bones to the points - bit shall increase your movement performance .

I had suspicions of this. The character is a lightly modified version of the zombie from weapon master VR. I’ll let him know about it too.

But wait with that, I will post some code snippets when ai will be back at home,
try to implement it, and measure the performance maybe it will already satisfy your needs.
(Since you didn’t say how much characters you want to have on the screen).

At least 100 zombies at a minimum 90fps in an procedural open world with physics

I will post some code later on today.
Well in General I’m also playing with RVO (toggling on/off)
My nav mesh also rebuilds in runtime (I am using distructible environment)

Oh one last thing - I am also not using any collision spheres or something like that on a characters
all the AI detections happens on a separate thread.

Ok, so here you go:

You have to create your own CharacterMovementComponent:
And add to it’s header:

UCLASS()
class YOUR_GAME_NAME_API UCM: public UCharacterMovementComponent
{
	GENERATED_BODY()

protected:
	//Init
	virtual void InitializeComponent() override;


public:

        //Useful to make sure that your characters are using the correct Component.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = StubCheck)
	bool m_dummyToMakeSure; 

	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;

private:
	float m_DeltaTime;
	int m_nTicksCount;
	int	m_nTickGroup;

	bool m_SkipFloorChecks;
};

In the CPP

void UCM::InitializeComponent()
{
	Super::InitializeComponent();

	m_nTickGroup = FMath::RandRange(3, 4);
	m_DeltaTime = 0.0f;
	m_SkipFloorChecks = FMath::RandBool();
	m_nTicksCount = 0;
}

void UCM::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
   	m_DeltaTime += DeltaTime;
	if (!CharacterOwner->GetMesh()->bRecentlyRendered)
	{
		if (++ m_nTicksCount % m_nTickGroup == 0)
		{
			m_nTicksCount = 0;
			DeltaTime = m_DeltaTime;
		}
		else
		{
			return;
		}
		
	}

	m_DeltaTime = 0.0f;

	//Call Default CharacterMovementComponent
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

This code snippet will cull of some of the Movement Component overhead for an invisible Characters.
Theoretically it should increase the number of Characters (that are off-screen) twice.

Please refer to this Wiki Page: on how to create a custom CharacterMovementComponent

1 Like

This is pre your fix. I get about 40 fps here with 80 ai. Gunna put in your fix and see what happens

Okay then after implementing my spanning trick
Just alter the spawns to be not in the same point
Make 3 regions for each wave to spawn at

1/3 Zombies Close sonthey will get every tick other 2/3 on a distant enough points tomapplyna distance optimization trick.

In this case Assuming you don’t have other bottle necks you might be able to reach 60-70 FPS.

The key is to cull the process - ot to process all of them in 1 frame - but process closest in 1 frame and span other accross multiple frames to cull of CPU bottle neck.

Also take a look of movement component - should your zombies ever fall somewhere ? if not - then tell MovementComponent not to check floor… etc etc…

My Optimization texhnique as is seems not to help you since it delas with the Zombies that are not rendered to screen, in your Screen shot I understand that you can see all of them - I would suggest to alter the trick a bit: I would still use the whole part of ocluded optimization, but I would add a distance sorting as well for instance I would tick Zombies in 2-3 groups 1 tick function for a close zombies and 2 more for a distant zombies while those who are pretty close should get every tick the distant zombies can skip ticks as well lets say you will devide them in 2 groups and tick group 1 on every even tick and group 2 on each odd tick…

In best case you get twice performance on an average case you will get 1/3 performance improve…
Picking a good distances treshholds will result for a human eye as a perfect movement even though you are skipping some ticks.

But 80 ai to 40 fps I have suspicions that you are failing at something else as well.
I would assume these hitboxes are a pitfall - but you shall measure the performance for a bottle necks first.

This trick lets call it a Tick span - won’t jump your FPS from 40 to 90
It may be beneficial with the addition Indeseibed here to get around 60fps…

Then go ahead and measure the other bottlenecks and try to optimize them 1by1

I will just add that I suppose that the screen shot is not an actual game play… Maybe if you post a screen shot from an actual gameplay I would assist more.

Hard to say what that would be like because I haven’t figured out the best way to spawn them on the map yet. Thinking random chance of a spawn point on a tile. I can drop a bunch of zombies in the game and show you what that might look like in view

I think that the most useful part for me was dropping BehaviourTrees
and tranferring the most heavy parts of AI to a separate thread
this alone allowed me to have ~ 100 AI with 120 FPS.

If you want you can take a look at my WIP game where I used it.

Run accross the map spawn as much AI as you can (by just running around the map , avoid werewolfs they are too strong) and look at the performance vs quality

https://drive.google.com/open?id=0B0IdKcPdt9ldRG1mZHJYS0liN2c

Good Luck Implementing!
Making AI on a separate thread is a huge work to do.
Go for it!

80 ai with best and worse scenarios on screen, captured in game from the htc vive. Still don’t have your fix in yet. Wanted to show what I have going on. This was still in the editor technically, it wasn’t launched as a standalone game.

A separate thread for ai in general should always be a thing in my opinion.

Daunting task for a noob. Also I played your game example and I get 90-120 fps with 20 or so ai on screen

I get ball park 90 fps with 20 zombies on my screen. Whats funny is that when I run it outside of vr mode, I get like 300 fps

My game is not for VR - and yes I have 300+ FPS
Then I suppose CharacterMovementComponent is not your bottleneck.

Please post your profiling results

TBH didnt even know it can run in VR

sorry i meant my game outside of vr mode

kind of new to profiling. what should I be testing

90-120 FPS in my game ?
Hmm what is your hardware ?

Profiling start from posting:

in console:
stat.unit
stat Unit or something like that
look here