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