Download

Root Motion (Montage) not playing correctly

Hi everyone,

I’m having issues with root motion replicating through client server.
It seems like I have all the networking parts setup correctly but I’m still seeing issues where no one but the original client who did the 3 part attack combo sees it correctly.

Using a dedicated server and 1 client I am able to see the issue (or 1 client as server and another client).
After the first montage, the 2nd attack is a spinning attack with quite a bit of root motion. After the first attack, the same montage (first attack) seems to get repeated forcing the server to “fix” the clients position.

Header




    UFUNCTION(NetMulticast, Reliable)
        void Multicast_PlayMontage(UAnimMontage* MontageToPlay);

    UFUNCTION(Server, Reliable, WithValidation)
        void Server_PlayMontage(UAnimMontage* MontageToPlay);

    UFUNCTION(BlueprintCallable, Category="Animations")
        void PlayMontage(UAnimMontage* MontageToPlay);

    void PlayMontageInMesh(UAnimMontage* MontageToPlay);




CPP



void AComboCombatActionCharacter::Attack()
{

    if (GetMovementComponent()->IsFalling()) {
        UE_LOG(LogTemp, Warning, TEXT("No jumping attack has been added yet"));
        return;
    }

    if (AttackMontages.Num() == 0) {
        UE_LOG(LogTemp, Warning, TEXT("%s does not have any montages in AttackMongages list"), *GetFName().ToString());
        return;
    }

    if (IsAttacking) {
        if (SaveAttack) {
            IsNextAttackPending = true;
        }
    }
    else {
        IsAttacking = true;

        this->PlayMontage(AttackMontages[CurrentAttackNumber]);
    }
}

void AComboCombatActionCharacter::PlayMontageInMesh(UAnimMontage* MontageToPlay) {
    ACCAPlayerState* playerState = GetPlayerState<ACCAPlayerState>();
    GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Playing montage: %s"), *MontageToPlay->GetFName().ToString()));
    UE_LOG(LogTemp, Warning, TEXT("UserId: %s Playing montage %s"), *playerState->UserId, *MontageToPlay->GetFName().ToString());

    UAnimMontage* montage = AttackMontages[CurrentAttackNumber];
    UAnimInstance* animInstance = GetMesh()->GetAnimInstance();
    TextColor = FColor::Green;

    if (HasAuthority() && MontageToPlay->GetFName().IsEqual(TEXT("Attack2_Montage"))) {
        UE_LOG(LogTemp, Warning, TEXT("Attack2 is about to play!"));
    }
    animInstance->Montage_Play(montage, AttackSpeed, EMontagePlayReturnType::MontageLength, 0, true);
}

void AComboCombatActionCharacter::PlayMontage(UAnimMontage* MontageToPlay) {
    Server_PlayMontage(MontageToPlay);
}

void AComboCombatActionCharacter::Server_PlayMontage_Implementation(UAnimMontage* MontageToPlay) {
    UE_LOG(LogTemp, Warning, TEXT("Playing on server"));
    Multicast_PlayMontage(MontageToPlay);
}

bool AComboCombatActionCharacter::Server_PlayMontage_Validate(UAnimMontage* MontageToPlay) {
    return true;
}

void AComboCombatActionCharacter::Multicast_PlayMontage_Implementation(UAnimMontage* MontageToPlay)
{
    if (HasAuthority()) {
        UE_LOG(LogTemp, Warning, TEXT("playing montage on server"));
    }
    else {
        UE_LOG(LogTemp, Warning, TEXT("playing montage on client"));
    }
    PlayMontageInMesh(MontageToPlay);
}


To help articulate the issue I will describe what each user is seeing with a dedicated server

[AttackingClient]: does combo montages, sees itself do correct montages, but root motion is pulled back by server
[OtherClient] Sees that the other client is attacking, but only sees 1 the first attack repeated throughout the combo

My current theory is that because I’m playing the montages pretty quickly, they aren’t able to play correctly on anything else but the client who originally played them, but what do I know? This is still my first week on Unreal and I’ve been stuck on this.

Here is a screen recording of the issue: UE4 Networking Montage Issue - YouTube

Thanks,
Imallic

Just a quick note: The issue still happens even if I remove the root motion

I have figured out a solution.

Instead of creating 3 montages for each attack, I now have a single montage that includes 3 sections (1 for each attack). Now when the character doesn’t click to continue the combo, a “StopAttack” RPC is sent to server/other clients to stop the attack montage