C++ Replicating Animations

I didnt test this code but can you please try this and report back?

// ACharacter.h
 
 public:
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
 class UAnimMontage* FireAnimation;
 
 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WeaponUsage)
 class USoundBase* FireSound;
 
 UFUNCTION(NetMulticast, Reliable)
 void MulticastSetFiring();
 
 UFUNCTION(Server, Reliable, WithValidation)
 void ServerSetFiring();
 
 UFUNCTION()
 void SetFiring();
 
 protected:
 void OnFire();
 
 // ACharacter.cpp
 
 void ACharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
 {
   Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 }
 
 void ACharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
 {
   // set up gameplay key bindings
   check(InputComponent);
 
   InputComponent->BindAction("Fire", IE_Pressed, this, &ACharacter::OnFire);
 }
 
 // WIP - Only Server can see animations of clients.
 void ACharacter::MulticastSetFiring_Implementation()
 {
    SetFiring();
 }
 
 void ACharacter::ServerSetFiring_Implementation()
 {
   MulticastSetFiring();
 }
 
 bool ACharacter::ServerSetFiring_Validate()
 {
   return true;
 }
 
 void ACharacter::OnFire()
 {
   if (HasAuthority())
   {
        SetFiring();
   }
   else
   {
        ServerSetFiring();
   }
 }
 
 void ACharacter::SetFiring()
 {
    // try and play the sound if specified
   if (FireSound != NULL)
   {
     UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
   }
 
   // try and play a firing animation if specified
   if (FireAnimation != NULL)
   {
     // Get the animation object for the arms mesh
     UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
     if (AnimInstance != NULL)
     {
       AnimInstance->Montage_Play(FireAnimation, 1.f);
     }
   }
 }

What’s wrong:

  • HOST can see the CLIENTS FireAnimation.

  • CLIENTS can’t see the HOST’s FireAnimation.

  • CLIENTS can’t see other CLIENTS FireAnimation.

What is needed:

What would need to be changed with the following code so that all CLIENTS and HOST can see any connected player’s FireAnimation? Is only a Replicated Multicast Function needed for the solution? What about only using a Replicated Server Function?

PLEASE NOTE:

bReplicates = true; // In player’s the constructor

I’ve already read this:

// ACharacter.h

public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay, Replicated)
  class UAnimMontage* FireAnimation;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WeaponUsage, Replicated)
  class USoundBase* FireSound;

UFUNCTION(NetMulticast, Unreliable)
    void MulticastSetFiring();

UFUNCTION(Server, Reliable, WithValidation)
    void ServerSetFiring();

protected:
void OnFire();

// ACharacter.cpp

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

  DOREPLIFETIME(ACharacter, FireAnimation);
  DOREPLIFETIME(ACharacter, FireSound);
}

void ACharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
  // set up gameplay key bindings
  check(InputComponent);

  InputComponent->BindAction("Fire", IE_Pressed, this, &ACharacter::OnFire);
}

// WIP - Only Server can see animations of clients.
void ACharacter::MulticastSetFiring_Implementation()
{
  // try and play the sound if specified
  if (FireSound != NULL)
  {
    UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
  }

  // try and play a firing animation if specified
  if (FireAnimation != NULL)
  {
    // Get the animation object for the arms mesh
    UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
    if (AnimInstance != NULL)
    {
      AnimInstance->Montage_Play(FireAnimation, 1.f);
    }
  }
}

void ACharacter::ServerSetFiring_Implementation()
{
  // try and play the sound if specified
  if (FireSound != NULL)
  {
    UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
  }

  // try and play a firing animation if specified
  if (FireAnimation != NULL)
  {
    // Get the animation object for the arms mesh
    UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
    if (AnimInstance != NULL)
    {
      AnimInstance->Montage_Play(FireAnimation, 1.f);
    }
  }
}

bool ACharacter::ServerSetFiring_Validate()
{
  return true;
}

void ACharacter::OnFire()
{
  if (Role < ROLE_Authority)
  {
    ServerSetFiring();
  }
  else
  {
    MulticastSetFiring();
  }
}

Hey ryanjon2040, thanks for the help!
Here’s the difference after applying your suggestion:

  • HOST can see the CLIENTS FireAnimation.

  • CLIENTS can’t see the HOST’s FireAnimation.

  • CLIENTS can see other CLIENTS FireAnimation.

  • Sound has doubled playing on all CLIENTS, but only once on HOST.

Any additional suggestions on how to get all three working?

Fantastic! The animations work correctly.

However, my CLIENTS are now playing the FireSound twice every shot.

Any thoughts?

I figured out the double playing sound problem by moving the following into the OnFire function.

if (FireSound != NULL)
  {
    UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
  }

Try changing the SetFiring to Multicast under Authority branch

Great to hear that OmicronVega. If the issue is resolved can you please mark my answer? This will help Epic track resolved answers. :slight_smile: