Download

OnTakeAnyDamage send some event to a client

How can I send an EVENT to client if OnTakeAnyDamage is executed only on a server? please see BP on screenshots

Code here or on website: hastebin
[SPOILER]



// HEADER file

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "SHealthComponent.generated.h"


DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams(FOnHeaalthChangedSignature, USHealthComponent*, HealthComponent, float, Health, float, HealthDelta, const class UDamageType*, DamageType, class AController*, InstigatedBy, AActor*, DamageCauser);

UCLASS( ClassGroup=(COOP), meta=(BlueprintSpawnableComponent) )
class COOPGAME_API USHealthComponent : public UActorComponent
{
    GENERATED_BODY()

public:    
    // Sets default values for this component's properties
    USHealthComponent();

protected:
    // Called when the game starts
    virtual void BeginPlay() override;

    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "HealthComponent")
    float DefaultHealth;

    UPROPERTY(Replicated, EditAnywhere, BlueprintReadOnly, Category = "HealthComponent")
    float Health;

    UFUNCTION()
    void HandleTakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser);

    virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const override;


public:
    UPROPERTY(BlueprintAssignable, Category = "Events")
    FOnHeaalthChangedSignature OnHealthChanged;

    float GetCurrentHealth();

    //** Returns health in percent form from 0 to 100%(0.0 to 1.0)
    UFUNCTION(BlueprintCallable, Category = "Health")
    float GetHealthPercent() const;
    UFUNCTION(BlueprintCallable, Category = "Health")
    float GetDefaultHealth() const;

    void SetHealth(float NewHealthValue);

};



// CPP file
// Fill out your copyright notice in the Description page of Project Settings.


#include "Public/Components/SHealthComponent.h"
#include "Net/UnrealNetwork.h"

// Sets default values for this component's properties
USHealthComponent::USHealthComponent()
{
    DefaultHealth= 100.0f;


    SetIsReplicated(true);
}


void USHealthComponent::BeginPlay()
{
    Super::BeginPlay();

    if(GetOwnerRole() == ROLE_Authority) {
        AActor* MyOwner = GetOwner();

        if (!MyOwner) {
            return;
        }

        MyOwner->OnTakeAnyDamage.AddDynamic(this, &USHealthComponent::HandleTakeAnyDamage);
    }
    Health = DefaultHealth;

}
void USHealthComponent::HandleTakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
{
    if (Damage <= 0.0f) {
        return;
    }

    Health = FMath::Clamp(Health - Damage, 0.0f, DefaultHealth);

    UE_LOG(LogTemp, Log, TEXT("Health Changed to: %s"), *FString::SanitizeFloat(Health));

    OnHealthChanged.Broadcast(this, Health, Damage, DamageType, InstigatedBy, DamageCauser);
// HERE must be a call to a client.
}


[/SPOILER]

I greatly appreciate any help!

Eyo,

This is a replication!
Link:

Make sure that your Player Character & HealthComponent is replicating by checking all the boxes in the constructors. I advise you to do an OnRep_Event instead of Multicast as this sure that the information will get through.

Here is my go-to Link when I need a reminder:
A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums,Using_ReplicatedUsing/_RepNotify_vars

Everything works fine except that I would like to have it replicated to a client, but OnTakeAnyDamage is executed on the server, so I can not send it to clients.

I will try to rewrite it as you said, but I am sure there’s a way to do it (like it is now in my case)
Thank you!

Eyo,

Sorry I might not have been clear enough.
If you are on the Server you can communicate back to the client in different ways, one of these ways is using an event called Multicast.
So right after “OnTakeAnyDamage” is being called you can call this Multicast event.

So basically, you would have 2 events, one is OnTakeAnyDamage (Server) & Multicast_OnTakeAnyDamage.

I normally do not recommend Multicast as the information might get lost. But replication is hard, so this is a start. Here is another link, even though it might be a bit old it have great pictures to illustrate Network:
http://cedric-neukirchen.net/Downloa…Neukirchen.pdf