Skip to content

Commit bbf4ea3

Browse files
committed
Added animation budget plugin implementation for bots
enabled animation budget plugin and implemented for the enemy minions. Included it with the significance manager
1 parent 4abe0bb commit bbf4ea3

File tree

8 files changed

+60
-12
lines changed

8 files changed

+60
-12
lines changed

ActionRoguelike.uproject

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,10 @@
450450
{
451451
"Name": "TraceSourceFilters",
452452
"Enabled": true
453+
},
454+
{
455+
"Name": "AnimationBudgetAllocator",
456+
"Enabled": true
453457
}
454458
],
455459
"TargetPlatforms": [
-2 KB
Binary file not shown.

Config/DefaultEngine.ini

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ r.PSOPrecache.ProxyCreationWhenPSOReady=1
1818
r.PSOPrecache.Validation=2
1919
; settings below for old bundled PSO steps to combine with PSO Precache
2020
r.ShaderPipelineCache.ExcludePrecachePSO=1
21+
; required for bundled PSO gathering
2122
r.ShaderPipelineCache.Enabled=1
2223
; start up background mode so we can run hitchless in a main menu
2324
r.ShaderPipelineCache.StartupMode=2
24-
25-
; required for bundled PSO gathering
25+
; Animation budgeter plugin
26+
a.Budget.Enabled=1
2627

2728
[DevOptions.Shaders]
2829
NeedsShaderStableKeys=true

Config/DefaultScalability.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44

55
[ViewDistanceQuality@0]
66
SigMan.SignificanceBucketSizeMultiplier=0.5
7+
a.Budget.BudgetMs=1.0
78

89
[ViewDistanceQuality@1]
910
SigMan.SignificanceBucketSizeMultiplier=0.8
11+
a.Budget.BudgetMs=1.0
1012

1113
[ViewDistanceQuality@2]
1214
SigMan.SignificanceBucketSizeMultiplier=1.0
15+
a.Budget.BudgetMs=1.0
1316

1417
[ViewDistanceQuality@3]
15-
SigMan.SignificanceBucketSizeMultiplier=1.5
18+
SigMan.SignificanceBucketSizeMultiplier=1.5
19+
a.Budget.BudgetMs=1.0

Source/ActionRoguelike/AI/RogueAICharacter.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "NiagaraComponent.h"
1111
#include "SharedGameplayTags.h"
1212
#include "SignificanceManager.h"
13+
#include "SkeletalMeshComponentBudgeted.h"
1314
#include "UI/RogueWorldUserWidget.h"
1415
#include "Components/CapsuleComponent.h"
1516
#include "GameFramework/CharacterMovementComponent.h"
@@ -18,11 +19,15 @@
1819
#include "Components/AudioComponent.h"
1920
#include "Components/CanvasPanel.h"
2021
#include "Perception/AISense_Damage.h"
22+
#include "IAnimationBudgetAllocator.h"
23+
#include "AnimationBudgetAllocator/Private/AnimationBudgetAllocatorModule.h"
2124

2225
#include UE_INLINE_GENERATED_CPP_BY_NAME(RogueAICharacter)
2326

2427

25-
ARogueAICharacter::ARogueAICharacter()
28+
ARogueAICharacter::ARogueAICharacter(const FObjectInitializer& ObjectInitializer)
29+
// Override the SkelMesh with the Anim Budget variant for balancing anim cost across all AI bots
30+
:Super(ObjectInitializer.SetDefaultSubobjectClass<USkeletalMeshComponentBudgeted>(ACharacter::MeshComponentName))
2631
{
2732
ActionComp = CreateDefaultSubobject<URogueActionComponent>(TEXT("ActionComp"));
2833
// Set some defaults, ideally we handle this through some data asset instead
@@ -63,6 +68,14 @@ void ARogueAICharacter::BeginPlay()
6368
{
6469
Super::BeginPlay();
6570

71+
// Only needs to enable the module once, placing in beginplay for convenience
72+
// They didn't expose the blueprint library, so we instead call directly into the module
73+
FAnimationBudgetAllocatorModule& AnimationBudgetAllocatorModule = FModuleManager::LoadModuleChecked<FAnimationBudgetAllocatorModule>("AnimationBudgetAllocator");
74+
if(IAnimationBudgetAllocator* AnimationBudgetAllocator = AnimationBudgetAllocatorModule.GetBudgetAllocatorForWorld(GetWorld()))
75+
{
76+
AnimationBudgetAllocator->SetEnabled(true);
77+
}
78+
6679
// Significance Manager
6780
{
6881
USignificanceManager* SigMan = USignificanceManager::Get(GetWorld());
@@ -96,19 +109,33 @@ void ARogueAICharacter::BeginPlay()
96109
DistanceSqrt *= 0.5f;
97110
}
98111

99-
// Note: AI can further define significance, for example,
100-
// while in combat or having the player as a known target we could increase its significance
112+
// Note: AI could further define significance, for example, while in combat or having the player as a known target we could increase its significance
101113

102114
// Negative distance to easily have larger distance mean lower significance
103115
return -DistanceSqrt;
104116
};
105117

118+
// Register with post significance function to easily tie-in with the animation budgeter
119+
// We could also choose to let the budgeter calculate the significance itself instead
120+
auto PostSignificanceFunc = [&](USignificanceManager::FManagedObjectInfo* ObjectInfo, float OldSignificance, float Significance, bool bFinal)
121+
{
122+
USkeletalMeshComponentBudgeted* BudgetMesh = Cast<USkeletalMeshComponentBudgeted>(GetMesh());
123+
BudgetMesh->SetComponentSignificance(Significance);
124+
};
125+
126+
127+
// Additional flag in the budgetter to allow us to 'toggle' and turn off certain animation features custom to the game, this could mean detaching components on our skeletal mesh
128+
// it's entirely game dependent on what we could throttle here
129+
USkeletalMeshComponentBudgeted* BudgetMesh = Cast<USkeletalMeshComponentBudgeted>(GetMesh());
130+
BudgetMesh->OnReduceWork().BindUObject(this, &ARogueAICharacter::OnReduceAnimationWork);
131+
106132
// Instead of passing the entire Actor, we can pass the minimal data, such as the RootComponent, or SkeletalMeshComponent
107133
// This should allow us to be more cache efficient (from simple testing this does run slightly faster than using the Actor)
108-
SigMan->RegisterObject(GetMesh(), SignificanceTag, SignificanceFunc);
134+
SigMan->RegisterObject(GetMesh(), SignificanceTag, SignificanceFunc, USignificanceManager::EPostSignificanceType::Concurrent, PostSignificanceFunc);
109135
}
110136
}
111137

138+
112139
void ARogueAICharacter::EndPlay(const EEndPlayReason::Type EndPlayReason)
113140
{
114141
// Remove from SigMan
@@ -241,6 +268,14 @@ void ARogueAICharacter::SignificanceLODChanged(int32 NewLOD)
241268
}
242269

243270

271+
void ARogueAICharacter::OnReduceAnimationWork(class USkeletalMeshComponentBudgeted* InComponent, bool bReduce)
272+
{
273+
UE_LOG(LogGame, Warning, TEXT("OnReduceAnimWork for bot %s, reducing = %s"), *GetName(), (bReduce ? TEXT("true") : TEXT("false")));
274+
275+
// @todo: Actually throttle some work, for example, detach certain components on the skeletal mesh IF we had any in the first place
276+
}
277+
278+
244279
FGenericTeamId ARogueAICharacter::GetGenericTeamId() const
245280
{
246281
// Fetch from the AI Controller who has built-in TeamId

Source/ActionRoguelike/AI/RogueAICharacter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ class ACTIONROGUELIKE_API ARogueAICharacter : public ACharacter, public IGeneric
6060
public:
6161

6262
virtual void SignificanceLODChanged(int32 NewLOD) override;
63+
64+
void OnReduceAnimationWork(class USkeletalMeshComponentBudgeted* InComponent, bool bReduce);
6365

6466
virtual FGenericTeamId GetGenericTeamId() const override;
6567

6668
virtual void PostInitializeComponents() override;
6769

68-
ARogueAICharacter();
70+
ARogueAICharacter(const FObjectInitializer& ObjectInitializer);
6971

7072
virtual void BeginPlay() override;
7173

@@ -81,4 +83,4 @@ class ACTIONROGUELIKE_API ARogueAICharacter : public ACharacter, public IGeneric
8183

8284
FTimerHandle OverlayTimerHandle;
8385

84-
};
86+
};

Source/ActionRoguelike/ActionRoguelike.Build.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public ActionRoguelike(ReadOnlyTargetRules Target) : base(Target)
3737
PrivateDependencyModuleNames.AddRange(new string[]
3838
{
3939
"MoviePlayer", // loading screen
40-
"RenderCore" // for PSO caching code access
40+
"RenderCore", // for PSO caching code access
41+
"AnimationBudgetAllocator"
4142
});
4243
}
4344
}

Source/ActionRoguelike/Performance/RogueSignificanceComponent.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,14 @@ float URogueSignificanceComponent::GetSignificanceByDistance(float DistanceSqrd)
193193
void URogueSignificanceComponent::UpdateParticleSignificance(float NewSignificance)
194194
{
195195
// Niagara Particle Systems
196-
TArray<UNiagaraComponent*> NiagaraSystems;
196+
// @todo: we don't need to call into niagara, the EffectType significance handler can do this for us...
197+
/*TArray<UNiagaraComponent*> NiagaraSystems;
197198
GetOwner()->GetComponents<UNiagaraComponent>(NiagaraSystems);
198199
199200
for (UNiagaraComponent* Comp : NiagaraSystems)
200201
{
201202
// Niagara uses 'int32 index' to set significance, you should map this with the input "float NewSignificance" (eg. not something between 0.0-1.0 as it gets rounded)
202203
203204
Comp->SetSystemSignificanceIndex(NewSignificance);
204-
}
205+
}*/
205206
}

0 commit comments

Comments
 (0)