Garmaine Staff asked 4 months ago

I am relatively new when it comes to unreal engine and c++.

I am trying to implement communication between multiple different pawn classes, that all inherit from the same custom pawn class. The goal is to be able to broadcast from one of the childclasses, to other childclasses of the parent and handle the delegate there (namely, add a reference of itself to an array owned by the caller).

My first idea was to simply declare the Delegate in the parent class so all the children can access the delegate easily.

Parent CGFCharacter.h

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CGFCharacter.generated.h"

// Polling for location event
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPollLocationsSignature, AActor*, OwningActor);

UCLASS()
class PROJECT_API ACGFCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    ACGFCharacter();

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

    UFUNCTION()
    void HandlePollLocations(AActor* OwningActor);

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    FPollLocationsSignature PollLocations;
};

CGFCharacter.cpp

ACGFCharacter::ACGFCharacter()
{
     // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = false;

    GetMesh()->SetupAttachment(GetArrowComponent());

    // Listen to location polling events
    PollLocations.AddDynamic(this, &ACGFCharacter::HandlePollLocations);

}

void ACGFCharacter::HandlePollLocations(AActor* OwningActor)
{
    ACGFPlayerCharacter* OwningCGFPlayerCharacter = Cast<ACGFPlayerCharacter>(OwningActor);
    if (OwningCGFPlayerCharacter)
    {
        OwningCGFPlayerCharacter->AddTarget(this);
        //UE_LOG(LogTemp, Log, TEXT("Tried adding %d"),this);
        //UE_LOG(LogTemp, Log, TEXT("Owningactor pointer %d"),OwningCGFPlayerCharacter);
    }
}

I broadcast it in child A like PollLocations.Broadcast(this);

Child B should be able to handle the event now since it also inherits from ACGFCharacter.

I got this to work only for the broadcaster (ClassA), but not for the class B.

My guess was that it was due to FPollLocationsSignature PollLocations being unique to each instance, so i tried changing it to static like

FPollLocationsSignature PollLocations; -> static FPollLocationsSignature PollLocations;
PollLocations.Broadcast(this); -> ACGFCharacter::PollLocations.Broadcast(this);
PollLocations.AddDynamic(this, &ACGFCharacter::HandlePollLocations); -> ACGFCharacter::PollLocations.AddDynamic(this, &ACGFCharacter::HandlePollLocations);

however, this gives me the following error:

Error    LNK2001    unresolved external symbol "public: static class FPollLocationsSignature ACGFCharacter::PollLocations" (?PollLocations@ACGFCharacter@@2VFPollLocationsSignature@@A)    CardGameFighter    E:\Users\User\Documents\Unreal Projects\Project\Intermediate\ProjectFiles\CGFCharacter.cpp.obj    1  

Error    LNK2001    unresolved external symbol "public: static class FPollLocationsSignature ACGFCharacter::PollLocations" (?PollLocations@ACGFCharacter@@2VFPollLocationsSignature@@A)    CardGameFighter    E:\Users\User\Documents\Unreal Projects\Project\Intermediate\ProjectFiles\CGFPlayerCharacter.cpp.obj    1  

Is there a way to get it working this way? What am i doing wrong? Is there a better way to achive this?

I have also seen people suggesting to use a global singleton in order to achive this, but i have no idea how to implement it, could someone give me a brief example?