Download

Issue replicating properties for animations

I’m converting a sample project from Blueprint to C++. I am trying to replicate to float values from my Character class to all clients which should replicate my character animation. These two float values are the MoveRight and MoveForward calculated in the CharacterMovement Blueprint. I save this to my character class and have it hooked up in my Animation blueprint. The character animation works fine locally, but is not being replicated to the server and/or back to the other clients. Any ideas on what I am doing wrong?



// AShooterCPPCharcter.h

// used to set input values so we can update the animation blueprint
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated)
float MoveForwardInput;

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated)
float MoveRightInput;




// AShooterCPPCharacter.cpp

AShooterCPPCharacter::AShooterCPPCharacter()
{
     // lots of stuff in here removed for clarity
     bReplicates = true;
}

void AShooterCPPCharacter::MoveForward(float Value)
{
    if ((Controller != NULL) && (Value != 0.0f))
    {
        // store value for use in Animation Blueprint
        MoveForwardInput = Value;

        // find out which way is forward
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);

        // get forward vector
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
        AddMovementInput(Direction, Value);
    }
}

void AShooterCPPCharacter::MoveRight(float Value)
{
    if ( (Controller != NULL) && (Value != 0.0f) )
    {
        // store value for use in Animation Blueprint
        MoveRightInput = Value;

        // find out which way is right
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);

        // get right vector 
        const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
        // add movement in that direction
        AddMovementInput(Direction, Value);
    }
}

void AShooterCPPCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
     Super::GetLifetimeReplicatedProps(OutLifetimeProps);

     DOREPLIFETIME(AShooterCPPCharacter, MoveForwardInput);
     DOREPLIFETIME(AShooterCPPCharacter, MoveRightInput);
}

Here is what my Animation Blueprint is doing. Notice the GET variable are coming from my AShooterCPP class directly and setting the local variables in the blueprint - both sets are set to replicate.

I think I worked it out. I needed to update my MoveForwardInput and MoveRightInput variables on the server. From there the rest of the Replication system takes over and propagates the values.

Added to my .h


UFUNCTION(Reliable, Server, WithValidation)
    void SetMoveForwardInput(float val);

    UFUNCTION(Reliable, Server, WithValidation)
    void SetMoveRightInput(float val);

From inside my MoveRight function instead of setting MoveForwardInput and MoveRightInput directly, I call SetMoveForward() and SetMoveRight() functions. The impementation of the macro in the header looks like this:



bool AShooterCPPCharacter::SetMoveForwardInput_Validate(float val)
{
    return true;
}

void AShooterCPPCharacter::SetMoveForwardInput_Implementation(float val)
{
    MoveForwardInput = val;
}

bool AShooterCPPCharacter::SetMoveRightInput_Validate(float val)
{
    return true;
}

void AShooterCPPCharacter::SetMoveRightInput_Implementation(float val)
{
    MoveRightInput = val;
}


That has solved my issue. I just don’t know if there is a more efficient way to do this. Should I create a new server function each time I need to update a variable on the server, or should I try to consolidate all my replication variables into on function?