Download

Unable to create custom animation nodes using EvaluateComponentSpace . Causing engine crash .

As the title implies , i am unable to create custom animation nodes that implements and overrides the EvaluateComponentSpace function . Doing so leads to a weird and complete crash . This is very strange because Evaluate , Initialize and Update works without problems . I tried it in a fresh new project , i even tried it in 4.16 . Still the same .

The code i have is the most simplistic animation graph and behaviour classes and structs !!




USTRUCT()
struct FAnimNode_SimpleIk : public FAnimNode_Base
{
	GENERATED_USTRUCT_BODY()

		// Input link
		UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Links)
		FComponentSpacePoseLink ComponentPose;

	// Current strength of the skeletal control
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))
		mutable float Alpha;


	/*
	* Max LOD that this node is allowed to run
	* For example if you have LODThreadhold to be 2, it will run until LOD 2 (based on 0 index)
	* when the component LOD becomes 3, it will stop update/evaluate
	* currently transition would be issue and that has to be re-visited
	*/
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Performance, meta = (DisplayName = "LOD Threshold"))
		int32 LODThreshold;

	UPROPERTY(Transient)
		float ActualAlpha;

public:



public:


	// FAnimNode_Base interface
	virtual void Initialize(const FAnimationInitializeContext& Context) override;
	virtual void CacheBones(const FAnimationCacheBonesContext& Context)  override;
	virtual void Update(const FAnimationUpdateContext& Context) override;
	virtual void EvaluateComponentSpace(FComponentSpacePoseContext& Output) override;


	// End of FAnimNode_Base interface


};






UCLASS()
class MYGAMEEDITOR_API UMyAnimGraphNode : public UAnimGraphNode_Base
{
	GENERATED_BODY()


		UPROPERTY(EditAnywhere, Category = Settings)
		FAnimNode_SimpleIk ik_Node;


	//~ Begin UEdGraphNode Interface.
	virtual FLinearColor GetNodeTitleColor() const override;
	virtual FText GetTooltipText() const override;
	virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
	//~ End UEdGraphNode Interface.

	//~ Begin UAnimGraphNode_Base Interface
	virtual FString GetNodeCategory() const override;
	//~ End UAnimGraphNode_Base Interface

	UMyAnimGraphNode(const FObjectInitializer& ObjectInitializer);
};


The .cpp file






void FAnimNode_SimpleIk::Initialize(const FAnimationInitializeContext& Context)
{


	ComponentPose.Initialize(Context);
}

void FAnimNode_SimpleIk::CacheBones(const FAnimationCacheBonesContext& Context)
{

	ComponentPose.CacheBones(Context);
}



void FAnimNode_SimpleIk::Update(const FAnimationUpdateContext& Context)
{
	ComponentPose.Update(Context);


}



void FAnimNode_SimpleIk::EvaluateComponentSpace(FComponentSpacePoseContext& Output)
{
	// Evaluate the input
	ComponentPose.EvaluateComponentSpace(Output);

	GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Red, "Mister Print");

}






When the project crashes , the first line of the log is :
*
Assertion failed: false [File:D:\Build++UE4+Release-4.15+Compile\Sync\Engine\Source\Runtime\Engine\Classes\Animation/AnimNodeBase.h] [Line: 570]
*

Support for creating your own animation graph nodes is very bad from what i researched , so i am a little desperate to get some advice here .

So the base “Evaluate( )” function will always throw an assert (false) because for some reason it is written that way.

In your FAnimNode_SimpleIk struct, add:



virtual void Evaluate(FPoseContext &Ouput) override;


Then



void FAnimNode_SimpleIk::Evaluate(FPoseContext &Ouput)
{
    // just need to override the Check(false) from the base. I dont think you actually need anything here.
}


Thanks for replying . Unfortunately , the problem still exist . I did try having both the evaluate and evaluatecomponentpose together before . While my project doesnt crash , evaluatecomponentpose never gets called . I tested by having a print on both .

EvaluateComponentSpace*

How are you calling the EvaluateComponentSpace function?

Got home and looked up the function again. The comment for Evaluate( ) is:



Called to evaluate local-space bones transforms according to the weights set up in Update().
You should implement either Evaluate or EvaluateComponentSpace, but not both of these.
This can be called on any thread.


Not sure if that is helpful but maybe you’ve been trying both and its causing an issue?

I would look at the base class and see if there is any more information on how to set it up, as in, what to override and what not to. There is a lot of “check(false)” in that class and I am assuming that is for a good reason. Sorry I can’t be more help but this isn’t something I’ve looked at before.

It is no different from the original code snippet i provided . There is a print function attached and thats it . I request you to try it for yourself and see if you can also reproduce the problem .

At this point , it is a paradoxical situation . If i dont use evaluate , the project throws an assert and it crashes . If i use evaluate along with evaluatecomponentspace , the latter is never called . I wish i knew why there is even a check(false) in the first place . It might even be a mistake from the engine developers , who knows …

I doubt its a mistake because it is used in many places, which is generally a sign of intent. I will see if I can track down which engine developer owns this bit of code and see if I can figure out a proper method in which you can extend and use these classes / structs for your own project.

I also just want to check.

UAnimGraphNode_Base is from the AnimGraph module, from the editor. Are you trying to use these from your games editor and have included the “AnimGraph” module to the editor build rules? This would be in MYGAMEEditor.Target.cs, where you can add “AnimGraph” to the ModuleNames.

I did include all possible modules in MyGame.Build.cs .

PublicDependencyModuleNames.AddRange(new string] { “Core”, “CoreUObject”, “Engine”, “InputCore”, “HeadMountedDisplay”, “AnimGraph”, “AnimGraphRuntime”, “UnrealEd”, “BlueprintGraph” });

I haven’t included anything within MYGAMEEditor.Target.cs at first , but i modified it according to your advice

OutExtraModuleNames.AddRange(new string] { “MyGameEditor”, “AnimGraph”, “AnimGraphRuntime”, “UnrealEd”, “BlueprintGraph” });

But unfortunately , the result is still the same error pointing to the Evaluate() assertion …

Looks to me like you are supposed to override only one of the two, and make sure that the other doesn’t get called. I’m guessing that’s done by this function in the graph node. If you’re not using FComponentSpacePoseLink in your implementation, that probably explains why the Evaluate method is getting called instead of EvaluateComponentSpace.

Awesome !! The problem is solved . Somebody gotta update those outdated tutorials with these information else somebody gonna break their systems :smiley:

There is this comment in the class header.

Glad you got it working. Good luck with your project.