NEED HELP: Creating Event in CPP. Actor Component and making it appear in Events tab

I tried making an Multi-Action Input Actor Component, and I made the Event inside my CPP. class. Thing is it doesn’t show up in Events tab. I tried recompiling it in VS but that’s not working either.
Am I missing something?

UCLASS(ClassGroup=(Input), meta=(BlueprintSpawnableComponent))
class MY_API UMultiActionInput : public UActorComponent
{
	GENERATED_BODY()

protected:
	// Called when the game starts
	virtual void BeginPlay() override;


	// #CUSTOM EVENTS START (No need to create Definitions for them, despite warnings.)

	// 
	UFUNCTION(BlueprintImplementableEvent)
	void CE_MAIA_Trigger_Hold();

	// 
	UFUNCTION(BlueprintImplementableEvent)
	void CE_MAIA_Trigger_Tap();

	// 
	UFUNCTION(BlueprintImplementableEvent)
	void CE_MAIA_Trigger_Release();

	// #CUSTOM EVENTS END

};


Bump.

I tried with this, but still it doesn’t show up in Events tab.

Header h.

UCLASS(Blueprintable, ClassGroup = (Input), meta = (BlueprintSpawnableComponent))
class PROJECT_API UMultiActionInput : public UActorComponent
{
	GENERATED_BODY()

public:

	// #CUSTOM EVENTS START (No need to create Definitions for them, despite warnings.)
	UFUNCTION(BlueprintImplementableEvent, Category = "Multi Action Events", meta = (DisplayName = "MAI Trigger (Hold)"))
	void CE_MAIA_Trigger_Hold();

CPP.

void UMultiActionInput::BP_MAI_On()
{
	CE_MAIA_Trigger_Hold();

}

BlueprintImplementableEvent and BlueprintNativeEvent are functions

What you’re looking for is DELCARE_DYNAMIC_MULTICAST_DELEGATE, and then create a UPROPERTY(BlueprintAssignable) property of the delegate that you created

Guess I can’t trust the tutorials.
They simply put UFUNCTION(BlueprintImplementableEvent) on Actors, and it works.

But NOBODY explains how to make the CPP Custom Events for Actor Components.

How am I supposed to set this up?

Header h.

#include "CoreMinimal.h"
#include "Delegates/Delegate.h"
#include "Components/ActorComponent.h"
#include "TestActorComponent.generated.h"


UCLASS( ClassGroup=(Input), meta=(BlueprintSpawnableComponent) )
class PROJECT_API UTestActorComponent : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UCndTestActorComponent();


	DECLARE_MULTICAST_DELEGATE(FCE_MAIA_Trigger_Hold);
	UPROPERTY(BlueprintAssignable, Category = "Input")
	FCE_MAIA_Trigger_Hold CE_MAIA_Trigger_Hold;

	UFUNCTION(BlueprintImplementableEvent, Category = "Events (Multi-Action)", meta = (DisplayName = "MAI Trigger (Hold)"))
	void CE_MAIA_Trigger_Hold();

LIke I said, it has to be a DECLARE_DYNAMIC_MULTICAST_DELEGATE to work with blueprints

I would suggest you look in the engine’s source code for things like that, there are infinite examples, and you can easily look up something that you’ve seen and want to replicate in the engine to see how it’s done

Okay, so… here’s what I did.

I declared the event first. Then I changed the UPROPERTY from ImplementableEvent to BlueprintAssignable in Header.

Header

	// #DECLARES START (No need to create Definitions for these Delegates, despite warnings.)
	// Declare CE - Multi Action Trigger (Hold)
	DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDEC_MAI_Trigger_Hold);

	// CE - Hold Action
	UPROPERTY(BlueprintAssignable, Category = "Events (Multi-Action)", meta = (DisplayName = "On MAI Trigger (Hold)"))
	FDEC_MAI_Trigger_Hold On_MAI_Trigger_Hold;
	void CE_MAIA_Trigger_Hold();

Then here’s what I did in CPP.

//  Broadcast Delegate - Hold
void UCndMultiActionInput::CE_MAIA_Trigger_Hold()
{
	On_MAI_Trigger_Hold.Broadcast();

}


That worked, Events appear, and even tested it out. It reads just fine.

For a bit off-topic:
I’m trying to make the Enum Input or Output pin to appear in the CPP. made custom events. Like with the CE_Im_Trying_To_Make.

I tried with adding the MAIA_Current Enum Variable to the brackets, but I always end up with “not enough / too much arguments” and etc.

Plus the retriggerable delay.

Functions in CPP.

void UMultiActionInput::BP_MAIA_Interact()
{
	MAIA_Current = EPlayerMAInputAction::MAIA_Interact;
	BP_MAI_On();
}

void UMultiActionInput::BP_MAI_On()
{

	MAI_InputTap = false;

	`// RETRIGGERABLE DELAY - 0.20 sec.`
	FLatentActionInfo LatentInfo;
	LatentInfo.CallbackTarget = this;
	LatentInfo.ExecutionFunction = "CE_MAIA_Trigger_Hold";
	UKismetSystemLibrary::RetriggerableDelay(this, MAI_HoldDuration, LatentInfo);

	if (MAI_InputTap) // true
	{
		// Do nothing
	}
	else // false
	{
		MAI_InputWheel = true;
		MAIT_Current = EPlayerMAInputType::MAIT_Hold;
	}

	CE_MAIA_Trigger_Hold(); // Call Event if Input is still held

}

void UMultiActionInput::BP_MAI_Off()
{

	if (MAI_InputWheel) // true
	{
		MAI_InputWheel = false;
		MAIT_Current = EPlayerMAInputType::MAIT_Release;
		CE_MAIA_Trigger_Release(); // Call Event if Input was Released
	}
	else // false
	{
		MAI_InputTap = true;
		MAIT_Current = EPlayerMAInputType::MAIT_Tap;
		CE_MAIA_Trigger_Tap(); // Call Event if Input was Tapped
	}

}

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDEC_MAI_Trigger_Hold, MAIA_Current, Current)

Okay, that did it:

Header (h.)

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDEC_MAI_Trigger_Hold, EPlayerMAInputAction, Input_Action_Type);

Source (cpp.)

//  Broadcast Delegate - Hold
void UMultiActionInput::CE_MAIA_Trigger_Hold()
{
	On_MAI_Trigger_Hold.Broadcast(MAIA_Current);

}

Just to fix the Retriggerable Delay, cuz right now is ignored for some reason, and I can call this as solved.


	// Initialize Default Values
	MAI_HoldDuration(0.20f)

	// #VARIABLES (PUBLIC) START:

	// This float sets time delay (in seconds) to trigger Hold Action
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Variables (Multi-Action)")
	float MAI_HoldDuration;

	// #VARIABLES (PUBLIC) END

void UMultiActionInput::BP_MAI_On()
{

	MAI_InputTap = false;

	// RETRIGGERABLE DELAY
	FLatentActionInfo LatentInfo;
	LatentInfo.CallbackTarget = this;
	LatentInfo.ExecutionFunction = "BP_MAI_On";
	LatentInfo.UUID = 00000;
	UKismetSystemLibrary::RetriggerableDelay(this, MAI_HoldDuration, LatentInfo);


	if (MAI_InputTap) // true
	{
		// Do nothing
	}
	else // false
	{
		MAI_InputWheel = true;
		MAIT_Current = EPlayerMAInputType::MAIT_Hold;
	}

	CE_MAIA_Trigger_Hold(); // Call Event if Input is still held

}

Alright, I figured it out somehow.
NOTE: Retriggerable Delay is not allowed in Functions. Use Timers instead.

First, I needed to create a Timer Handle in Header.

Header (h.)

private:

	// Make Timer Handle for Delay
	FTimerHandle MAI_TimerHandle;

Then in the source, set up a Delay Timer and Extra Function.

Source (CPP.)

void UMultiActionInput::BP_MAI_On()
{

	// Delay: Set up a timer - MAI_TimerHandle
	GetWorld()->GetTimerManager().SetTimer(MAI_TimerHandle, this, &UMultiActionInput::BP_MAI_Hold_Trigger, MAI_HoldDuration, false);

}


void UMultiActionInput::BP_MAI_Hold_Trigger()
{
	// This function will be called after MAI_HoldDuration seconds
	CE_MAIA_Trigger_Hold(); // Call Event if Input is still held
}

void UMultiActionInput::BP_MAI_Off()
{
	// This function will is to be called, if held Action Button is Released
	// Delay: Clear the timer - MAI_TimerHandle
	GetWorld()->GetTimerManager().ClearTimer(MAI_TimerHandle);
}

Guess I can call this as solved.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.