BlueprintImplementableEvent not working on UActorComponents

I’ve created my custom ActorComponent, and declared a BlueprintImplementableEvent inside it.

My goal was to have it overriden in blueprints, but it doesn’t show when I click on “Override” button, on Functions category, and nor when I search for it on blueprint actions menu.

The same was tested under a AActor derived class, and I could override it easily.

Also, I’ve tried to call the BlueprintImplementableEvent method inside c++, and when I try to open my project, it crashes.

Crash message:

Assertion failed: !IsUnreachable() [File:D:\Build++UE4+Release-4.16+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp] [Line: 1139]
SF_BasePayloadComponent /Engine/Transient.None:ProjectilePayload Function: ‘/Script/Projectiles_TestRoom.SF_BasePayloadComponent:BlueprintOnActivated’

My code:

.h

UFUNCTION()
	void OnPayloadActivated(UActorComponent* Component, bool bReset);

	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnActivatedPayload"))
	void BlueprintOnActivated(UActorComponent* Component, bool bReset);

.cpp

void USF_BasePayloadComponent::OnPayloadActivated(UActorComponent* Component, bool bReset)
{
	BlueprintOnActivated(Component, bReset);
}

It doesn’t seem that you can have BlueprintImplementableEvent in Actor Components. What you can do is use delegates.
You could try something like this:
In your .h file:

    //Delegate Signature
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FBlueprintOnActivated, UActorComponent*, Component, bool, bReset);
    
//Below where you have all  your variables
  protected:  //or public or private whatever suits your needs

  UPROPERTY(BlueprintAssignable,   meta = (DisplayName = "OnActivatedPayload"))
  FBlueprintOnActivated BlueprintOnActivated;

Then in your .cpp file:

 void USF_BasePayloadComponent::OnPayloadActivated(UActorComponent* Component, bool bReset)
 {
     BlueprintOnActivated.Broadcast(Component, bReset);
 }

Be sure to select the component in the editor for your event to show up in blueprints.

Thanks for the answer.

It should be possible to add BlueprintImplementableEvent because ReceiveBeginPlay, inside UActorComponent class, does so.

UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName = "Begin Play"))
void ReceiveBeginPlay();

The problem is extending from the class seems to unable this property to be used…
Good news is that yout solution works

It really sounds a bug, so I’ll leave this post till someone from Epic give the final words about this case

Hey Gbr-

I’m glad you were able to find a solution that works for you. As a note, you can use BlueprintImplementableEvents inside an actor component. The key is that you have to make your actor component class Blueprintable in the UCLASS() macro in order to create a blueprint of the component. Then, in the component’s blueprint, you can override the function. When the component blueprint is added to an actor and you call your function on that component, you will get the component blueprint’s implementation.

Cheers

Oh, nice! Thanks for the answer, didn’t come to my mind to explore the UCLASS macro parameters before searching for a workaround…

Hi ,

I was not able make it work this manner, the editor crashes while loading the project.

The crash issue:

Assertion failed: !IsUnreachable()
[File:D:\Build++UE4+Release-4.16+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp]
[Line: 1139] None
/Engine/Transient.TRASH_Default__BP_ProjTestPayload_C_0
Function:
‘/Script/SF_Weapons_Projectiles.SF_BasePayloadComponent:Blueprint_OnActivatedEvent’

What I’ve done:

declared these two methods:

//Overrides in blueprint
UFUNCTION(BlueprintImplementableEvent, Category = "Payload", meta = (DisplayName = "OnActivatedPayload"))
void Blueprint_OnActivatedEvent();
	
// Calls delegate
UFUNCTION()
virtual void OnPayloadActivated(UActorComponent* Component, bool bReset);

Defined as:

void USF_BasePayloadComponent::BeginPlay()
{
	Super::BeginPlay();	
	OnComponentActivated.AddDynamic(this, &USF_BasePayloadComponent::OnPayloadActivated);
}


void USF_BasePayloadComponent::OnPayloadActivated(UActorComponent* Component, bool bReset)
{
	UE_LOG(LogTemp, Warning, TEXT("Called OnPayloadActivated"));
	Blueprint_OnActivatedEvent();
}

[continues next post…]

[pt II]

I’ve added that Log entry in order to check if it’s called while loading, inside the log file. And it’s being called:

[2017.07.07-13.55.58:199][  0]LogAIModule: Creating AISystem for world Map_ThirdPerson
[2017.07.07-13.55.58:210][  0]LogEditorServer: Finished looking for orphan Actors (0.000 secs)
[2017.07.07-13.55.58:225][  0]LogTemp:Warning: Called OnPayloadActivated
[2017.07.07-13.55.58:226][  0]LogWindows: Windows GetLastError: The operation completed successfully. (0)
[2017.07.07-13.56.04:835][  0]LogWindows:Error: === Critical error: ===
[2017.07.07-13.56.04:835][  0]LogWindows:Error: 
[2017.07.07-13.56.04:835][  0]LogWindows:Error: Assertion failed: !IsUnreachable() [File:D:\Build\++UE4+Release-4.16+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp] [Line: 1139] 
[2017.07.07-13.56.04:835][  0]LogWindows:Error: None /Engine/Transient.TRASH_Default__BP_ProjTestPayload_C_0  Function: '/Script/SF_Weapons_Projectiles.SF_BasePayloadComponent:Blueprint_OnActivatedEvent'

The problem is that, inside the ActorComponent class, the engine does exactly the same as I’m trying to reach with the ReceiveBeginPlay method…

My UCLASS config is the following:
UCLASS(Blueprintable, BlueprintType, abstract, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )

class SF_WEAPONS_PROJECTILES_API USF_BasePayloadComponent : public UActorComponent

…And sorry for having to reopen this case

Hey Gbr-

I added “Blueprintable” to my UCLASS, then added the following to the .h file

UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category = test)
	void RandomTestFunction();

In the editor I created a blueprint of my component with:

191735-testcomp.png

As well as an actor blueprint with my component attached. In the actor blueprint I called the function from my component blueprint: