How do I check for a valid cast?

Hello community,

right now, I am trying to implement the IGenericTeamAgentInterface for the AI and I got it up and running. But I encounter a problem I cannot solve on my own, as all of my search keywords seem to be too generic to deliver an appropriate result.
I am not new to C++ but to Unreal and I kinda miss a lot.

I am overriding the GetGenericTeamId() function from the TeamAgentInterface inside a PlayerCharacter. But as most of the logic is stored inside the PlayerController, the function basically only calls this one instead. The Engine crashes by that procedure at the moment where I hit simulate instead preview. I assume that the PlayerCharacter is missing a valid PlayerController in that case as the VS Exception is “Access violation reading location 0x0000000000000000”. So far so good, but how do I check for a valid memory location in that case?

Here is the code:

FGenericTeamId ALAME_PlayerCharacter::GetGenericTeamId() const
{    	
	return Cast<IGenericTeamAgentInterface>(GetController())->GetGenericTeamId();
}

Something like this:

FGenericTeamId ALAME_PlayerCharacter::GetGenericTeamId() const
{
Controller* YouController = Cast<IGenericTeamAgentInterface>(GetController())->GetGenericTeamId();

if (YouController)
{
	return Cast<IGenericTeamAgentInterface>(GetController())->GetGenericTeamId();
}

return nullptr;

}

I’m not sure “Controller” is the right class, but I hope you get the idea.

Using the “if(bool)” you can check if the cast was valid. Storing the cast on a pointer is so you don’t have to cast twice; on the check and on the return.

pointers “filled” with nullptr don’t crash the engine.

Thank you, your answer was not directly applicable but it points me in the right direction.

“Cast(GetController())->GetGenericTeamId();” returns a FGenericTeamId Object (not a pointer). To tinker around with that knowledge, I split up the whole expression. Also, the return value of the whole function itself is an object, not a pointer.

The new function solves the problem. And I could be happy with it, but still, I ask my self if it is the most optimized and convenient solution to the problem. Does anyone have an opinion on that? And, do I ever have to save all my return values like that? Sounds like an immense overhead to me.

Here’s the new function:

FGenericTeamId ALAME_PlayerCharacter::GetGenericTeamId() const
{
	FGenericTeamId value = 255;

	AController* currentController = GetController();
	if (currentController)
	{
		IGenericTeamAgentInterface* currentInterface = Cast<IGenericTeamAgentInterface>(currentController);
		if (currentInterface)
			value = Cast<IGenericTeamAgentInterface>(GetController())->GetGenericTeamId();
	}
	return value;
}

The step to create the “currentInterface” is not needed, as it hadn’t failed until now.

The first check is unnecessary. You can immediately try to cast the result of GetController(), even if it is null. When you try to cast a nullptr, you get back a nullptr, no harm done.

There’s also no reason to cast twice. Save the result of the cast in a variable and use the variable.

1 Like

This. That bothered me so much that he did it like that.