Bind function to OnCharacterMovementUpdated in C++?

I’m trying to do this operation in C++:

I already have UpdateSceneOffset in code, so this works fine, but I feel like I should be able to do the actual bind in code as well. I can’t find anything about this for some reason. What is the C++ equivalent of this?

One possible solution would be to override the CharacterMovement class and this function, depending on what you’re trying to accomplish, this might be too much work.

You might want to look into this, I think it might be the literal c++ correlation to your blueprint: UCharacterMovementComponent::OnMovementUpdated | Unreal Engine Documentation

Hey SlimeQ-

You should be able to add OnCharacterMovementUpdated.AddDynamic(this, &AMyCharacter::Something); to the constructor of your character class. This will then call the AMyCharater::Something() function whenever CharacterMovementUpdated is called (or whatever other function you replace “Something” with).

Cheers

OnMovementUpdated looks like exactly what I need… however I have no idea how to use it. I can’t even find it in intellisense. Any ideas?

got it! i already had a custom CharacterMovement class from the Shooter Game Sample, so I just added an override for OnMovementUpdated and used it to call a similar function on the owner like so:

void UShooterCharacterMovement::OnMovementUpdated(float DeltaSeconds, const FVector & OldLocation, const FVector & OldVelocity)
{
	AShooterCharacter* ShooterCharacterOwner = Cast<AShooterCharacter>(PawnOwner);
	ShooterCharacterOwner->OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity);
}

this works perfectly. thanks a bunch

I rescind my prior statement. It was far from perfect. It’s hard to say for certain but I suspect that it was only being executed on about half of movement updates. I had to switch back because it was causing more problems than it was worth. DRATS

This seems extremely promising but I’m having some trouble using the AddDynamic function. According to intellisense the closest match is __Internal_AddDynamic which has a different signature: (UserClass*, TBaseDynamicDelagate, FName). Once I type AddDynamic intellisense shows me the signature you’ve suggested, but it will not compile. I’m not totally sure how to make this work. Googling has revealed that the signature was changed in 4.12, but I’m too much of a noob to understand what exactly the solution is.

Intellisense does not always recognize syntax that comes from engine code. You can use AddDynamic by itself if you ignore the Intellisense warning. As for the signature, the signature for OnCharacterMovementUpdated comes from the FCharacterMovementUpdatedSignature delegate, which has the signature of (float DeltaSeconds, FVector OldLocation, FVector OldVelocity). You’ll need to make sure that your function has a matching signature and you should be good to go.

After attempting to do this by adding the following line:

OnCharacterMovementUpdated.AddDynamic(this, &AVRShooterCharacter::OnMovementUpdated);

I am getting the following error on compilation:

Error C:\Users\quinc\Documents\Unreal Projects\ShooterGame\Source\ShooterGame\Private\Player\VRShooterCharacter.cpp(33) : error C2664: 'void TBaseDynamicMulticastDelegate::__Internal_AddDynamic(UserClass *,void (__cdecl AVRShooterCharacter::* )(float,FVector,FVector),FName)': cannot convert argument 2 from 'void (__cdecl AVRShooterCharacter::* )(float,const FVector &,const FVector &)' to 'void (__cdecl AVRShooterCharacter::* )(float,FVector,FVector)'

OnMovementUpdated has a signature identical to the signature you’ve suggested. Am I missing something?

I fixed the compilation error, but the function still isn’t being called. I am binding with the following line:

OnCharacterMovementUpdated.AddDynamic(this, &AVRShooterCharacter::ReallyUpdateMovement);

and AVRShooterCharacter::ReallyUpdateMovement looks like this:

void AVRShooterCharacter::ReallyUpdateMovement(float DeltaSeconds, FVector OldLocation, FVector OldVelocity) {
	if (GEngine) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("ReallyUpdateMovement"));
	}
	UpdateVROrigin(OldLocation);
}

where UpdateVROrigin is the critical function. I’m not even getting the debug message. Something is not working.

Is the binding being done inside the AVRShooterCharacter class or another class? Additionally, are you adding the binding code inside the constructor? Can you run a test for me by adding the following code to your character class and let me know if you get the debug message during PIE:

in AVRShooterCharacter.h

UFUNCTION(BlueprintCallable, Category = Test)
	void Rando(float DeltaSeconds, FVector OldLocation, FVector OldVelocity);

in AVRShooterCharacter::AVRShooterCharacter()

OnCharacterMovementUpdated.AddDynamic(this, &AVRShooterCharacter::Rando);

in AVRShooterCharacter.cpp

void AVRShooterCharacter::Rando(float DeltaSeconds, FVector OldLocation, FVector OldVelocity)
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 4.f, FColor::Magenta, TEXT("Some Stuff Gets Printed"));
	}
}

I got it working. I had created a function in a parent class called OnMovementUpdated and it was breaking everything. Thanks!

Edit: For whatever reason I also had to bind during PostInitializeComponents when extending the ShooterCharacter from the Shooter Game Sample. I’m not sure why.