But, I don’t think I can do it because an Actor doesn’t have the PlayerInputComponent.
Another way is using something that I have found in blueprints called “Interactions By Event Dispatcher”, but I’m not sure how to do it in C++ or if it is a good idea to use it.
Create a class ABaseInteractableActor (you can create an interface instead);
Make a variable in the character of type ABaseInteractableActor (or of the interface type);
The button actor contains a trigger; when the character overlaps the trigger, the button actor writes itself into the character’s variable, and sets it to nullptr when overlap ends;
In the character class, when you press Use, check if that variable is valid, and if it is, call the needed function in the button actor.
An option could be: Create a c++ interface with a multicast delegate. Apply the interface to your character (c++) and use that delegate to broadcast on every interaction. On the door, add a sphere component that checks every overlapping pawn for the interface, if found bind a function to the delegate and unbind on end overlap.
You won’t need to include the character class in the door, just the interface. So if the player is overlapping and presses a button, everything bound (the door in this case) will know btn was pressed and will do stuff.
Thanks, but I’m dealing with this all the day and I don’t know how to do it.
I have added this header file using Visual Studio to do it.
#pragma once
#include "EnableActionButtonTriggerInterface.generated.h"
UINTERFACE(MinimalAPI, Blueprintable)
class UEnableActionButtonTriggerInterface : public UInterface
{
GENERATED_BODY()
};
class IEnableActionButtonTriggerInterface
{
GENERATED_BODY()
public:
/** Add interface function declarations here */
};
After that, I have closed Unreal Editor and Visual Studio, generate Visual Studio projects, and compile the project.
But I get some errors, one of them is:
Cannot open file EnableActionButtonTriggerInterface.generated.h.
And now, I don’t know how to continue.
Is it correct the way I have added the header file?
How do I have to continue?
Is there any example find code file to see what I have to do?
I called mine Interface_Interact, so it generated two classes in a single .h called UInterface_Interact and IInterface_Interact.
Add your delegate in the .h:
// Above class
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FInteractMultiDelegate);
// ....
// In IInterface_Interact, under public
FInteractMultiDelegate InteractDelegate;
What you will use to bind will be InteractDelegate. That is all for this interface.
In your characters .h, add the interface. To do that you must add the #include and then declare it. It should look something like this:
// No interface
UCLASS()
class AMyCharacter : public ACharacter
{
// ...
}
// w/ interface
UCLASS()
class AMyCharacter : public ACharacter, public IInterface_Interact
{
// ...
}
To use the delegate, just use the declared InteractDelegate in the characters cpp. For example: I created an interact action and bound it to &AMyCharacter::Interact. This is all it does:
In the cpp #include the interface and in the overlap function check for it to bind:
// Try to save a pointer to the actor with interface
ActorWithInterface = Cast<IInterface_Interact>(OtherActor);
// Check if the actor had the interface
if (ActorWithInterface != nullptr)
{
ActorWithInterface->InteractDelegate.AddUniqueDynamic(this, &AOverlapTriggerActor::TriggerDoor);
UE_LOG(LogTemp, Warning, TEXT("[ AOverlapTriggerActor::SphereBeginOverlap ] : Binded"));
}
By binding AOverlapTriggerActor::TriggerDoor we are telling to run that function everytime the player presses the interact input. We could also bind at the same time other functions from same or different classes to the same delegate.
On end overlap you’ll need to unbind so that it doesnt get triggered even when pawn walks away:
if (ActorWithInterface != nullptr)
{
ActorWithInterface->InteractDelegate.RemoveDynamic(this, &AOverlapTriggerActor::TriggerDoor);
}
… and that’s it. Seems like much but think setting it up this way allows to keep minimum code in the character and everything else encapsulated in their respective class.
Character doesnt have to know what it is interacting with and the interactibles dont have to know it was the character that told them to interact.