Upcasting AActor to Interface

Hi guys,

I have an interface (Unreal interface) called IInteraction. From this, is derived another Interface (cpp interface) called IPickable. And then I have a BasePickup which is child from an AActor and IPickable. So, in theory, BasePickup is also a IInteraction.

Now, in another part of the code, I have a delegate to OnComponentBeginOverlap, where I am receiving the AActor that has been collided. I want to work with IInteraction interface because I want to register this IInteractions collisions into a vector of IInteractions, regardless the specific type. So, I can work with pickups, or with some other kind of interactuable objects.

But here it comes the problem. Once I receive the colliding AActor, and I try to upcast to IInteraction, it always returns nullptr. It happens the same if I cast to IPickable.

I attach some code snippets:

IInteraction interface:

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Interaction.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UInteraction : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class TERROR_API IInteraction
{
	GENERATED_BODY()
};

IPickable interface

class TERROR_API IPickable : public IInteraction
{

public:
	virtual void Pickup() = 0;
	virtual UPickableData* GetData() = 0;
};

BasePickup

#pragma once

#include "Pickable.h"

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BasePickup.generated.h"

UCLASS(Abstract)
class TERROR_API ABasePickup : public AActor, public IPickable
{
	GENERATED_BODY()
	
public:	
	ABasePickup();

public:
	UPickableData* GetData() override;
	virtual void Pickup() override {};

Some other place:

void AMainCharacter::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	IInteraction* interactionTriggered = Cast<IInteraction>(OtherActor);
	if (interactionTriggered != nullptr)
	{
		mActionZone.AddInteractionObject(interactionTriggered);
	}
}

So, found the issue.

The issue it’s that I was trying to upcast into a cpp interface, and it seems that UE4 does not support that from an AActor. Once I changed the IPickable to a Unreal interface, it worked.

For those who wonder how to have interfaces inheriting from other interfaces, here is the trick:

UINTERFACE(MinimalAPI)
class UPickable : public UInteraction (<--- here is the trick).
{
	GENERATED_BODY()
};

/**
 * 
 */
class TERROR_API IPickable : public IInteraction (<--- here is the trick)
{

	GENERATED_BODY()

public:

	virtual void Pickup() = 0;
	virtual UPickableData* GetData() = 0;

};

Source: Interfaces inheriting from other interfaces - C++ Programming - Unreal Engine Forums

1 Like

Cast function is UE4 things that check in UE4 reflection system if cast is valid, in order for cast with that function the classes you cast to need naturally to be visible to reflection system, thats why turning to unreal interface worked.

Note that Cast function is UE4 API feature and you can still use native C++ casting, bypassing UE4 reflection system. Ofcorse it risky as it throws responsibility for check to you, but if Cast function fails in some way, it is way to go.

That’s interesting… Because one thing I tried is to use dynamic_cast casting from c++ instead of using the UE4 cast. But still did not work since it was returning null.

I will have to make some tests on that…