I’ve created a CombatComponent for my character and trying to just change attack status by pressing key.
All works but not see status for Simulated proxies.
Could smbd give me a hint what I’m doing in a wrong way.
Image:
[SPOILER]
Code of the ActorComponent:
[SPOILER]
CombatComponent.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Net/UnrealNetwork.h"
#include "CombatComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MULTIPLAYER_01_API UCombatComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UCombatComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps);
//
UPROPERTY(Replicated, VisibleAnywhere, Category = "ServerActionState")
FString AttackStatus = "NONE";
UFUNCTION(Server, Reliable, WithValidation)
void Server_AttackStatus(const FString& _AttackStatus);
void Server_AttackStatus_Implementation(const FString& _AttackStatus);
bool Server_AttackStatus_Validate(const FString& _AttackStatus);
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void SimulatedTick(float DeltaTime);
void Attack01();
private:
class ACharacter* Owner = nullptr;
};
CombatComponent.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "CombatComponent.h"
#include "Animation/AnimInstance.h"
#include "GameFramework/Character.h"
#include "DrawDebugHelpers.h"
// Sets default values for this component's properties
UCombatComponent::UCombatComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
SetIsReplicated(true);
}
// Called when the game starts
void UCombatComponent::BeginPlay()
{
Super::BeginPlay();
// Set owner reference
Owner = Cast<ACharacter>(GetOwner());
}
// Called every frame
void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (ServerActionState.bIsRolling)
{
Owner->AddMovementInput(Owner->GetActorForwardVector(), 1.0, true);
}
if (GetOwnerRole() == ROLE_Authority)
{
DrawDebugString(GetWorld(),
FVector(0, 0, 150),
AttackStatus,
GetOwner(),
FColor::White,
0.1f);
}
//
if (GetOwnerRole() == ROLE_AutonomousProxy)
{
DrawDebugString(GetWorld(),
FVector(0, 0, 150),
AttackStatus,
GetOwner(),
FColor::White,
0.1f);
}
//
if (GetOwnerRole() == ROLE_SimulatedProxy)
{
SimulatedTick(DeltaTime);
}
}
void UCombatComponent::SimulatedTick(float DeltaTime)
{
DrawDebugString(GetWorld(),
FVector(0, 0, 150),
AttackStatus,
GetOwner(),
FColor::White,
0.1f);
}
void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps)
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UCombatComponent, AttackStatus);
}
void UCombatComponent::Server_AttackStatus_Implementation(const FString& _AttackStatus)
{
AttackStatus = _AttackStatus;
}
bool UCombatComponent::Server_AttackStatus_Validate(const FString& _AttackStatus)
{
return true;
}
void UCombatComponent::Attack01()
{
if (!Owner)
{
return;
}
// Update Listen-Client state on the server for simulation purposes
if (GetOwnerRole() == ROLE_Authority && Owner->IsLocallyControlled())
{
UE_LOG(LogTemp, Warning, TEXT("Server Listen-Client ATTACK"))
AttackStatus = "Attack_01";
Server_AttackStatus("Attack_01");
}
//
if (GetOwnerRole() == ROLE_AutonomousProxy)
{
UE_LOG(LogTemp, Warning, TEXT("Autonomous ATTACK"))
AttackStatus = "Attack_01";
Server_AttackStatus("Attack_01");
}
if (GetOwnerRole() == ROLE_SimulatedProxy)
{
UE_LOG(LogTemp, Warning, TEXT("Simulated ATTACK"))
AttackStatus = "Attack_01";
Server_AttackStatus("Attack_01");
}
}
[/SPOILER]
PS
Replicated checkbox for the component is ON too.