component inheriting from sphere component crashing the editor

So i made myself a nice class

InteractionComponent.h


UCLASS(ClassGroup = Shapes, meta = (BlueprintSpawnableComponent))
class PROJECT_API UInteractionComponent : public USphereComponent
{
	GENERATED_BODY()

public:
	UInteractionComponent(const FObjectInitializer& ObjectInitializator);
	void InitializeComponent() override;

	UPROPERTY(BlueprintReadOnly, Category = Interaction)
		TArray<AActor*> ActorsInRange;
	
	void Collide(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
	void EndCollide(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
	
};


InteractionComponent.cpp


UInteractionComponent::UInteractionComponent(const FObjectInitializer& ObjectInitializator)
	:Super(ObjectInitializator)
{
	bWantsInitializeComponent = true;
}

void UInteractionComponent::InitializeComponent()
{
	OnComponentBeginOverlap.AddDynamic(this, &UInteractionComponent::Collide);
	OnComponentEndOverlap.AddDynamic(this, &UInteractionComponent::EndCollide);
}

void UInteractionComponent::EndCollide(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	IUsableInterface* PotentialUsable = Cast<IUsableInterface>(OtherActor);
	if (PotentialUsable)
	{
		ActorsInRange.Add(OtherActor);
	}
}

void UInteractionComponent::Collide(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	//IUsableInterface* PotentialUsable = Cast<IUsableInterface>(OtherActor);
	//if (PotentialUsable)
	//{
	//	PotentialUsable->Activate(OtherActor);
	//	//ActorsInRange.RemoveSingle(OtherActor);
	//}
	/*if (OtherActor->GetClass()->ImplementsInterface(UUsableInterface::StaticClass()))
	{
		IUsableInterface* CastedActor = Cast<IUsableInterface>(OtherActor);
		CastedActor->Activate(OtherActor);
	}*/
}

that uses a nice interface

UsableInterface.h


UINTERFACE(meta = (CannotImplementInterfaceInBlueprint))
class DESOLATION_API UUsableInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};
class DESOLATION_API IUsableInterface
{
	GENERATED_IINTERFACE_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "Interact")
		virtual void Interact(AActor* ActorInteracting);
	UFUNCTION(BlueprintCallable, Category = "Interact")
		virtual void Activate(AActor* ActorInteracting);
	UFUNCTION(BlueprintCallable, Category = "Interact")
		virtual void Deactivate(AActor* ActorInteracting);
};

UsableInterface.h


UUsableInterface::UUsableInterface(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{

}


void IUsableInterface::Interact(AActor* ActorInteracting)
{

}

void IUsableInterface::Activate(AActor* ActorInteracting)
{

}

void IUsableInterface::Deactivate(AActor* ActorInteracting)
{

}

But there are 2 problems

  1. When i try to add it to actor, editor crashes with an error, this happened rather suddenly because i could add the component before without a problem

MachineId:820100A64EDCA7F07592C98C5FB5D60E
UserName:Illusive

Unknown exception - code 00000001 (first/second chance not available)

Assertion failed: InvocationList CurFunctionIndex ] != InDelegate [File:C:\Users\Illusive\Documents\GitHub\UnrealEngine\Engine\Source\Runtime\Core\Public\UObject\ScriptDelegates.h] [Line: 435] 

KERNELBASE + 37901 bytes
UE4Editor_Core!FOutputDeviceWindowsError::Serialize() + 285 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsplatformoutputdevices.cpp:95]
UE4Editor_Core!FOutputDevice::Logf__VA() + 248 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\misc\outputdevice.cpp:144]
UE4Editor_Core!FDebug::AssertFailed() + 1042 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\misc\outputdevice.cpp:224]
UE4Editor_Desolation!TMulticastScriptDelegate<FWeakObjectPtr>::AddInternal() + 226 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\uobject\scriptdelegates.h:433]
UE4Editor_Desolation!UInteractionComponent::InitializeComponent() + 280 bytes [c:\users\illusive\documents\unreal projects\desolationgame\desolation\source\desolation\private\inventory\interactioncomponent.cpp:18]
UE4Editor_Engine!UActorComponent::RegisterComponentWithWorld() + 910 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\actorcomponent.cpp:631]
UE4Editor_Engine!USCS_Node::ExecuteNodeOnActor() + 514 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\scs_node.cpp:89]
UE4Editor_Engine!USimpleConstructionScript::ExecuteScriptOnActor() + 610 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\simpleconstructionscript.cpp:296]
UE4Editor_Engine!AActor::ExecuteConstruction() + 421 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\actorconstruction.cpp:372]
UE4Editor_Engine!AActor::RerunConstructionScripts() + 2509 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\actorconstruction.cpp:291]
UE4Editor_Engine!AActor::PostEditChangeProperty() + 438 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\engine\private\actoreditor.cpp:63]
UE4Editor_CoreUObject!UObject::PostEditChange() + 52 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\coreuobject\private\uobject\obj.cpp:215]
UE4Editor_UnrealEd!FBlueprintEditorUtils::PostEditChangeBlueprintActors() + 305 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\unrealed\private\kismet2\blueprinteditorutils.cpp:5841]
UE4Editor_Kismet!FBlueprintEditor::OnBlueprintChanged() + 48 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\kismet\private\blueprinteditor.cpp:2626]
UE4Editor_Kismet!TBaseSPMethodDelegateInstance<0,FBlueprintEditor,0,TTypeWrapper<void> __cdecl(UBlueprint * __ptr64)>::Execute() + 76 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:283]
UE4Editor_Kismet!TBaseSPMethodDelegateInstance<0,FBlueprintEditor,0,void __cdecl(UBlueprint * __ptr64)>::ExecuteIfSafe() + 60 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:381]
UE4Editor_Engine!TBaseMulticastDelegate<void,UBlueprint * __ptr64>::Broadcast() + 148 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegatesignatureimpl_variadics.inl:978]
UE4Editor_UnrealEd!FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified() + 853 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\unrealed\private\kismet2\blueprinteditorutils.cpp:1598]
UE4Editor_Kismet!SSCSEditor::AddNewNode() + 479 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\kismet\private\sscseditor.cpp:2722]
UE4Editor_Kismet!SSCSEditor::AddNewComponent() + 200 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\kismet\private\sscseditor.cpp:2683]
UE4Editor_Kismet!SSCSEditor::PerformComboAddClass() + 547 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\kismet\private\sscseditor.cpp:2366]
UE4Editor_Kismet!TBaseSPMethodDelegateInstance<0,SSCSEditor,0,TTypeWrapper<void> __cdecl(TSubclassOf<UActorComponent>)>::Execute() + 74 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:283]
UE4Editor_Kismet!TBaseSPMethodDelegateInstance<0,SSCSEditor,0,void __cdecl(TSubclassOf<UActorComponent>)>::ExecuteIfSafe() + 63 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:381]
UE4Editor_UnrealEd!TBaseDelegate<void,TSubclassOf<UActorComponent> >::ExecuteIfBound() + 45 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegatesignatureimpl_variadics.inl:511]
UE4Editor_UnrealEd!SComponentClassCombo::OnAddComponentSelectionChanged() + 226 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\editor\unrealed\private\scomponentclasscombo.cpp:178]
UE4Editor_UnrealEd!TBaseSPMethodDelegateInstance<0,SComponentClassCombo,0,TTypeWrapper<void> __cdecl(TSharedPtr<FComponentClassComboEntry,0>,enum ESelectInfo::Type)>::Execute() + 106 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:283]
UE4Editor_UnrealEd!TBaseSPMethodDelegateInstance<0,SComponentClassCombo,0,void __cdecl(TSharedPtr<FComponentClassComboEntry,0>,enum ESelectInfo::Type)>::ExecuteIfSafe() + 101 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegateinstancesimpl_variadics.inl:381]
UE4Editor_UnrealEd!TBaseDelegate<void,TSharedPtr<FComponentClassComboEntry,0>,enum ESelectInfo::Type>::ExecuteIfBound() + 97 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\public\delegates\delegatesignatureimpl_variadics.inl:507]
UE4Editor_UnrealEd!SListView<TSharedPtr<FComponentClassComboEntry,0> >::Private_SignalSelectionChanged() + 547 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\public\widgets\views\slistview.h:612]
UE4Editor_UnrealEd!STableRow<TSharedPtr<FString,0> >::OnMouseButtonUp() + 1113 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\public\widgets\views\stablerow.h:365]
UE4Editor_Slate!<lambda_de96dc3471181973108233c6db1f9843>::operator()() + 188 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3857]
UE4Editor_Slate!FEventRouter::Route<FReply,FEventRouter::FToLeafmostPolicy,FPointerEvent,<lambda_de96dc3471181973108233c6db1f9843> >() + 215 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:208]
UE4Editor_Slate!FSlateApplication::ProcessMouseButtonUpEvent() + 592 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3860]
UE4Editor_Slate!FSlateApplication::OnMouseUp() + 278 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\slate\private\framework\application\slateapplication.cpp:3821]
UE4Editor_Core!FWindowsApplication::ProcessDeferredMessage() + 3433 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsapplication.cpp:1361]
UE4Editor_Core!FWindowsApplication::DeferMessage() + 299 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsapplication.cpp:1657]
UE4Editor_Core!FWindowsApplication::ProcessMessage() + 3483 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsapplication.cpp:742]
UE4Editor_Core!FWindowsApplication::AppWndProc() + 98 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsapplication.cpp:604]
user32 + 105425 bytes
user32 + 104666 bytes
UE4Editor_Core!FWindowsPlatformMisc::PumpMessages() + 118 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\core\private\windows\windowsplatformmisc.cpp:774]
UE4Editor!FEngineLoop::Tick() + 3434 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\launch\private\launchengineloop.cpp:2193]
UE4Editor!GuardedMain() + 478 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\launch\private\launch.cpp:131]
UE4Editor!GuardedMainWrapper() + 26 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
UE4Editor!WinMain() + 249 bytes [c:\users\illusive\documents\github\unrealengine\engine\source\runtime\launch\private\windows\launchwindows.cpp:202]
UE4Editor!__tmainCRTStartup() + 329 bytes [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c:618]


  1. can someone tell me how to call an interface method in c++?

Problem 1 happens because you’re binding the delegates more than once per instance, since InitializeComponents() is probably called more than once per instance. What you should do is bind the delegates in the constructor, and UE4 will automatically instance them for you (or you could probably do OnComponentBeginOverlap.Contains() to check whether the function is already bound). Additionally, you need to mark Collide and EndCollide as UFUNCTION()s because the dynamic delegate system needs it. Problem 2 is solved by reading the wiki page on C++ interfaces.

Thank you the UFUNCTION() was the thing i was missing.

There is another slight issue because it seems that this constructor is being called twice, so i have additional function added to each delegate


UInteractionComponent::UInteractionComponent(const FObjectInitializer& ObjectInitializator)
	:Super(ObjectInitializator)
{
	OnComponentBeginOverlap.AddDynamic(this, &UInteractionComponent::Collide);
	OnComponentEndOverlap.AddDynamic(this, &UInteractionComponent::EndCollide);
}


and i can’t even seem to be able to do this


UInteractionComponent::UInteractionComponent(const FObjectInitializer& ObjectInitializator)
	:Super(ObjectInitializator)
{
	if(!OnComponentBeginOverlap.Contains(&UInteractionComponent::Collide))
		OnComponentBeginOverlap.AddDynamic(this, &UInteractionComponent::Collide);
	if (!OnComponentEndOverlap.Contains(UInteractionComponent::EndCollide))
		OnComponentEndOverlap.AddDynamic(this, &UInteractionComponent::EndCollide);
}


Because Contains() expects something called TScriptDelegate