Hello! I hope you can help me with this issue. I have multiple custom AnimNotifyStates that I use in my game, many of which have variables that I set at runtime. The most obvious example would be my UTctAnimNotifyState, which is my parent class for all my custom AnimNotifyStates, and has a Timer variable to track the elapsed time since the AnimNotifyState started.
The problem I have found with these variables is that (I presume for optimization) they seem to be shared or overwritten in cases where different characters are executing the same AnimNotifyState at once.
I have come up with strange and cumbersome solutions for this, e.g Having a TMap<UAnimNotifyState, TypeOfVariableIWantToTrack> for each AnimNotifyState, but it demands a lot of code and makes it very tricky.
Is there a way to easily disable this optimization so that each active NotifyState contains isolated data (variables) that will not be overriden? Alternatively, is there a quick and easy solution for this that doesn’t involve changing my entire architecture for this? (tracking state in the character instead of the notify state is not a viable change to make at this point in development).
I know the AnimNotifyState functions have the FAnimNotifyEventReference& EventReference parameter. Maybe I can use this to store and update data in this way? I can’t seem to wrap my head around how this would work.
Code:
.h File
// Tessera Studios placeholder copyright - All rights reserved
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "TctAnimNotifyState.generated.h"
/**
* Base anim notify state class.
*/
UCLASS()
class TESSERACOMMONTOOLS_API UTctAnimNotifyState : public UAnimNotifyState
{
GENERATED_BODY()
public:
UTctAnimNotifyState();
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
virtual void NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference) override;
protected:
UPROPERTY(BlueprintReadOnly, Transient, Category = "Properties")
float Duration = 0.0f;
UPROPERTY(BlueprintReadOnly, Transient, Category = "Properties")
float Timer = 0.0f;
};
.cpp file
// Tessera Studios placeholder copyright - All rights reserved
#include "Anim/Notifies/TctAnimNotifyState.h"
UTctAnimNotifyState::UTctAnimNotifyState()
{
}
void UTctAnimNotifyState::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference)
{
Super::NotifyBegin(MeshComp, Animation, TotalDuration, EventReference);
Duration = TotalDuration;
Timer = 0.0f;
if (IsValid(Animation))
{
Duration /= Animation->RateScale;
}
}
void UTctAnimNotifyState::NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference)
{
Super::NotifyTick(MeshComp, Animation, FrameDeltaTime, EventReference);
Timer += FrameDeltaTime;
if (Timer > Duration) Timer = Duration; // clamp it to duration, just in case
}
Thankyou so much in advance for any help! I hope you have a quick solution for this since I have been struggling with this issue for weeks.
Kinds regards,
Jorge Dinarés.