2

I would like to receive a multicast event from the LeapMotion plugin in C++. From their documentation, they mention the following things:

> On Hand Grabbed Event called when a leap hand grab gesture is
> detected. Signature: const FLeapHandData&, Hand, see FLeapHandData
> 
> FLeapHandSignature OnHandGrabbed;

So in my .cpp file I added the following:

ALeapMotionGesture::ALeapMotionGesture()
{
    PrimaryActorTick.bCanEverTick = true;
    Leap = CreateDefaultSubobject<ULeapComponent>(TEXT("Leap"));
}

void ALeapMotionGesture::BeginPlay()
{
    Super::BeginPlay();

    if (Leap != nullptr) {
        FScriptDelegate Delegate;
        Delegate.BindUFunction(this, FName("HandGrabbed"));
        Leap->OnHandGrabbed.Add(Delegate);
    }
}

void ALeapMotionGesture::HandGrabbed(const FLeapHandData& Hand) {
    UE_LOG(LogTemp, Warning, TEXT("Hand Grabbed"));
}

As it is the first time I'm using delegates in Unreal/C++, I would like to know how I could make it work?

It compiles fine however I do not receive any events.

3
  • 1
    Did you add UFUNCTION() on your function HandGrabbed? Commented Mar 24, 2019 at 7:52
  • Thanks, adding the UFUNCTION solved my issue! Commented Mar 25, 2019 at 3:17
  • Congratulations, If you accept my comment as answer, I would be more happy, thank you! Commented Mar 25, 2019 at 4:32

2 Answers 2

5

Add UFUNCTION() on your function HandGrabbed

Sign up to request clarification or add additional context in comments.

Comments

3

Short Answer

Replace:

void ALeapMotionGesture::BeginPlay()
{
    Super::BeginPlay();

    if (Leap != nullptr) {
        FScriptDelegate Delegate;
        Delegate.BindUFunction(this, FName("HandGrabbed"));
        Leap->OnHandGrabbed.Add(Delegate);
    }
}

with:

void ALeapMotionGesture::BeginPlay()
{
    Super::BeginPlay();

    if (Leap != nullptr) {
        Leap->OnHandGrabbed.AddDynamic(this, &ALeapMotionGesture::HandGrabbed);
    }
}

Long Answer

ULeapComponent::OnHandGrabbed is a FLeapHandSignature which is declared with DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam.

The LeapMotion README says to consult the Multi-cast documentation, but they are using dynamic delegates, so you actually need to read the Dynamic Delegates documentation. There you will see you should use the AddDynamic helper macro which generates the function name string for you.

Dynamic Delegates make use of helper macros that take care of generating the function name string for you.

From the Dynamic Delegates doc:

Dynamic Delegate Binding

BindDynamic( UserObject, FuncName )

Helper macro for calling BindDynamic() on dynamic delegates. Automatically generates the function name string.

AddDynamic( UserObject, FuncName )

Helper macro for calling AddDynamic() on dynamic multi-cast delegates. Automatically generates the function name string.

RemoveDynamic( UserObject, FuncName )

Helper macro for calling RemoveDynamic() on dynamic multi-cast delegates. Automatically generates the function name string.

Side Note

Dynamic delegates are serialized, which sometimes results in unexpected behavior. For example, you can have delegate functions being called even though your code is no longer calling AddDynamic (because a serialized/saved actor serialized the results of your old code) or you might call AddDynamic even though the deserialization process already did that for you. To be safe, you probably should call RemoveDynamic before AddDynamic. Here's a snippet from FoliageComponent.cpp:

// Ensure delegate is bound (just once)
CapsuleComponent->OnComponentBeginOverlap.RemoveDynamic(this, &AInteractiveFoliageActor::CapsuleTouched);
CapsuleComponent->OnComponentBeginOverlap.AddDynamic(this, &AInteractiveFoliageActor::CapsuleTouched);

2 Comments

Thanks for the very detailed answer Doug! In the end, both your piece of code and mine worked, the issue was what Protoss mentionned above - I forgot the UFUNCTION(). In this case, is it better to use the Multicast delegate as I did or switch to the Dynamic one as you proposed? (Or doesn't matter?)
Ah yeah, I've forgot UFUNCTION before as well. I'm actually not sure if one is better than the other. One nice thing about the AddDynamic is that it creates the function string for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.