How to modify a Component based on Authority in C++?

Hi there. I basicly try to call a function in C++ which does the exactly same as this Blueprint does:

!60930-

(It should set the color of a cube on the clientside to green and on the serverside to red)

My problem is, that I need to call this function from a C++ script, which is called only on the server. In a second step I need to get a specific component and set a Value. Unfortunately I failed at both of these steps.

I spent hours trying out different ways to achieve it, but it just won’t work. I could really need some help!

When do you want this to happen? Arbitrarily throughout the game? At startup? ???

Anyway, the easiest way is to have a “SetColour” function that you call on the server that calls a “Multicast_SetColour” function that will do what you have in the bp.

First off: Thank you for the answer!

The actor will be spawned at runtime…
I tried to do what you said. Here is the Code:

AuthorityTest.h

#pragma once

#include "GameFramework/Actor.h"
#include "AuthorityTest.generated.h"

UCLASS()
class AURA_API AAuthorityTest : public AActor
{
	GENERATED_BODY()

public:
	//Constructor
	AAuthorityTest();

	//Variables
	UPROPERTY(EditAnywhere, Category = Main)
		UMaterialInstance* ClientMat;
	UPROPERTY(EditAnywhere, Category = Main)
		UMaterialInstance* ServerMat;
	UPROPERTY(EditAnywhere, Category = Main)
		UStaticMeshComponent* MeshComp;		//Doesn't show up!

	//Functions
	virtual void BeginPlay() override;
	UFUNCTION()
		void SetColour();
	UFUNCTION(NetMulticast, Reliable, WithValidation)
		void Multicast_SetColour();
		virtual void Multicast_SetColour_Implementation();
		virtual bool Multicast_SetColour_Validate();
};

AuthorityTest.cpp

#include "Aura.h"
#include "AuthorityTest.h"


AAuthorityTest::AAuthorityTest()
{
	PrimaryActorTick.bCanEverTick = false;
	bReplicates = true;
}

void AAuthorityTest::BeginPlay()
{
	Super::BeginPlay();
	
	UE_LOG(LogTemp, Warning, TEXT("Begin called"));

	if (this->HasAuthority())
	{
		SetColour();
	}
}


void AAuthorityTest::SetColour()
{
	Multicast_SetColour();
}


void AAuthorityTest::Multicast_SetColour_Implementation()
{
	if (HasAuthority())
	{
		UE_LOG(LogTemp, Warning, TEXT("Called on Server"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("Called on Client"));
	}
}

bool AAuthorityTest::Multicast_SetColour_Validate()
{
	return true;
}

Right now it does show “Begin called”, “Called on sServer”, “Begin called”. It doesn’t execute the function on the client though.

An other problem is, that I don’t get the StaticMeshComponent to show up in the defaults. Which is why I can’t select on which mesh I want to swap the material.

Seems like I can’t use comments with code and only answer the question directly.

Hrm. How are you spawning the actor at runtime?

Okay I figured it out.

How to call the function on the server and the client:
You can use replicated variables which trigger a RepNotify-Function/Event. It’s explained here: RepNotify

How to access a StaticMeshComponent:
A StaticMeshComponent won’t show up in the defaults, but it will be accessible in the Blueprint. To link the component, you have to simply set the connection in the construction-graph.

This might work for you, but you should be aware of the differences between replication and rpcs. RPCs should be used for gameplay important things. Replicated variables aren’t guaranteed to be replicated to clients within a reasonable timeframe or in any specific order, only that given enough time they should update on the client.

You should still look into why RPCs were not working for you, because if they weren’t it’s probably symptomatic of a larger issue.

You can read more here

It doesn’t make a difference if I spawn the actor at runtime or not. As soon as I start the RPC only on the server, it won’t get called on the client (As I did in the code).

  • Server-RPCs seam to work perfectly for me.
  • With Client-RPCs I just don’t know what to use them for. They will only be called if the Client owns them, which doesn’t seem very useful in a Server-Listener scenario.
  • Multicast-RPCs seam to do exactly the same as the Server-RPC’s

With Client-RPCs I just don’t know
what to use them for. They will only
be called if the Client owns them,
which doesn’t seem very useful in a
Server-Listener scenario.

What would you expect these to do? That is their function.

Multicast-RPCs seam to do exactly the
same as the Server-RPC’s

Multicast-RPCs get called everywhere when called from the server. This is what you want to call from the server if you want it to be called on all clients.