Download

Help with Root Motion Forces (not animation related)

I’ve been looking a lot but couldn’t find noone talking about using root motion in code.

There is only the official documentation, which lacks of (maybe too basic, but I can’t figure it out) information on ussage: https://docs.unrealengine.com/en-US/…rce/index.html

For those willing to use it online:
1-
You have to define the RootMotionSource in all clients and server, server replicates, but all of the clients must have “initialized” that movement also.
2- Seems you have to set the movement mode of the character movement component to “flying” or otherwise It won’t work

I want to move characters in a replicated game. The constant force is pretty straight forward and It works as expected. The issue comes with the FRootMotionSource_MoveToDynamicForce as It makes my character move “jitter” and at some point when updating the target location in the Tick() event, I get a segmentation error

The code I’m using is rather simple:



// [client & server]
void AGrifballCharacter::StartPursuingMovement() {
    if (IsValid(Target) == false)
    {
        return;
    }

    FRootMotionSource_MoveToDynamicForce* MoveToForce = new FRootMotionSource_MoveToDynamicForce();
    MoveToForce = new FRootMotionSource_MoveToDynamicForce();
    MoveToForce->InstanceName = TEXT("Pursue");
    MoveToForce->AccumulateMode = ERootMotionAccumulateMode::Override;
    MoveToForce->Priority = 5;
    MoveToForce->Duration = 1.0f;
    MoveToForce->StartLocation = this->GetActorLocation();
    MoveToForce->InitialTargetLocation = Target->GetActorLocation();
    MoveToForce->FinishVelocityParams.Mode = ERootMotionFinishVelocityMode::MaintainLastRootMotionVelocity;
    RootMotionID = this->GetCharacterMovement()->ApplyRootMotionSource(MoveToForce);
    PursueMove = MoveToForce;
    GetCharacterMovement()->SetMovementMode(MOVE_Flying, EActionState::Pursuing);

}

// [client & server]
void AGrifballCharacter::UpdatePursueMovementTarget() {
    if (IsValid(Target) )
    {
        if (PursueMove)
        {
            PursueMove->SetTargetLocation(Target->GetActorLocation());
        }
    }
}

// [client & server]
void AGrifballCharacter::StopRootMovement() {
    FRootMotionSource* ConstantForce = this->GetCharacterMovement()->GetRootMotionSourceByID(RootMotionID).Get();
    if (ConstantForce && ConstantForce->IsActive()) {
        this->GetCharacterMovement()->RemoveRootMotionSourceByID(RootMotionID);
        GetCharacterMovement()->SetMovementMode(MOVE_Walking, 0);
        PursueMove = nullptr;
    }
}


The class properties used to store active motion are:


// Identifier for current active Root Motion (not animation related)
    uint16 RootMotionID;

    FRootMotionSource_MoveToDynamicForce* PursueMove;

Obviously I’m doing something wrong, but I don’t really get It. Tried to find usage examples in google, the forums and in Github without luck…

Any advise would be really appreciated.

Thank you,

  • Nesjett