Download

Delegate Binding Question

After spending quite a bit of time writing code to allow characters to find other characters, determine line of sight, etc., I stumbled upon UPawnSensingComponent. I’m now in the process of throwing away what I’ve written to leverage this built-in functionality instead.

I added a pawn sensing component to my character:



    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Awareness)
	TSubobjectPtr<class UPawnSensingComponent> PawnSensing;


I’m hitting problems when it comes time specify the OnSeePawn delegate and the OnHearNoise delegate. I tried following the instructions at https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Delegates/index.html and tried adding this to my constructor:



    FSharedRef< FHearNoiseDelegate > HearNoiseDelegate( new FHearNoiseDelegate() );
    PawnSensing->OnHearNoise(&AEnemyCharacter::OnHearNoise);


but I get this error:



    EnemyCharacter.cpp:11:5: error: no template named 'FSharedRef'; did you mean 'TSharedRef'?
    FSharedRef< FHearNoiseDelegate > HearNoiseDelegate( new FHearNoiseDelegate() );


The example code shows using FSharedRef. Is that a typo, or is there a header I need to include? Better yet, does anybody have an example of registering the OnHearNoise and/or OnSeePawn delegates, or something a little more in-depth on UE4’s delegates?

Thanks!

Okay, I’ve made some progress. I’ve got OnSeePawn working, but still having trouble with the OnHearNoise.

Here’s what I’ve done so far.

First, added the Pawn Sensing Component declaration in my header file:



        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Awareness)
	TSubobjectPtr<class UPawnSensingComponent> PawnSensor;


Then, in my constructor, I create it:



    PawnSensor = PCIP.CreateDefaultSubobject<UPawnSensingComponent>(this, TEXT("Pawn Sensor"));


I then created two methods to receive the notifications. After exploring in the headers, I realized that the hear noise takes three parameters and the see pawn method takes one, so I wrote these two simple functions (both are declared as UFUNCTIONs in the header):



void AEnemyCharacter::OnHearNoise(APawn *OtherPawn, const FVector Location, float Volume)
{
    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Heard an Actor"));
}

void AEnemyCharacter::OnSeePawn(APawn *OtherPawn)
{
    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Saw an Actor"));
}


Next, I overrode PostInitializeComponents() and registered my OnSeePawn delegate:



void AEnemyCharacter::PostInitializeComponents()
{
    Super::PostInitializeComponents();
    PawnSensor->OnSeePawn.AddDynamic(this, &AEnemyCharacter::OnSeePawn);
}


And this works beautifully. Every half-second, I get a notification if the enemy can see the player.

But, I can’t figure out how to bind the OnHearSound delegate. The .AddDynamic call doesn’t work on PawnSensor->OnHearNoise. Any thoughts or suggestions would be appreciated still.

Just to be sure, do you have other pawns that have a PawnNoiseEmitterComponent that are making sounds?

Yeah. My problem was a compilation problem, but with a little help from the AnswerHub, I got it sorted. My method signature was wrong - second argument needed to be passed by reference.

Thanks, though!