I’m trying to understand how this works, and made a simple actor to verify my assumptions. All it does is the server picks a random target, sets a position variable (and pubs it), and both server and client use that to set the actor location, however the position received is always 0. Any ideas?
edit: The code below now works
.H
#pragma once
#include "Engine.h"
#include "CoreUObject.h"
#include "MessageEndpoint.h"
#include "SyncedActor.generated.h"
USTRUCT()
struct FSyncPositionMessage
{
GENERATED_BODY()
public:
UPROPERTY()
FVector Position;
};
UCLASS()
class ASyncedActor
: public AActor
{
GENERATED_BODY()
public:
ASyncedActor();
UPROPERTY(VisibleAnywhere)
FVector Position;
UPROPERTY(VisibleAnywhere)
FVector TargetPosition;
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
virtual void BeginDestroy() override;
private:
TSharedPtr<FMessageEndpoint, ESPMode::ThreadSafe> MessageEndpoint;
FTimerHandle SelectTargetHandle;
void SelectTarget();
void HandlePositionMessage(const FSyncPositionMessage& Message, const TSharedRef<IMessageContext, ESPMode::ThreadSafe>& Context);
};
CPP:
#include "SyncedActor.h"
#include "MessageEndpoint.h"
#include "MessageEndpointBuilder.h"
ASyncedActor::ASyncedActor()
{
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
}
void ASyncedActor::BeginPlay()
{
Super::BeginPlay();
MessageEndpoint = FMessageEndpoint::Builder("ASyncedActor")
.Handling<FSyncPositionMessage>(this, &ASyncedActor::HandlePositionMessage)
.Build();
if (!HasAuthority())
MessageEndpoint->Subscribe<FSyncPositionMessage>();
else
{
SelectTarget();
GetWorld()->GetTimerManager().SetTimer(SelectTargetHandle, this, &ASyncedActor::SelectTarget, 3.0f, true);
}
}
void ASyncedActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (HasAuthority())
{
Position = FMath::Lerp(Position, TargetPosition, DeltaSeconds);
FSyncPositionMessage* SyncMessage = new FSyncPositionMessage();
SyncMessage->Position = Position;
MessageEndpoint->Publish(SyncMessage, EMessageScope::All);
}
FVector Size(25, 25, 25);
this->SetActorLocation(Position);
}
void ASyncedActor::BeginDestroy()
{
Super::BeginDestroy();
}
void ASyncedActor::SelectTarget()
{
TargetPosition = FMath::VRand() * 100;
TargetPosition += FVector(-600, 0, 100);
}
void ASyncedActor::HandlePositionMessage(const FSyncPositionMessage& Message, const TSharedRef<IMessageContext, ESPMode::ThreadSafe>& Context)
{
GEngine->AddOnScreenDebugMessage(-1, 1.0, FColor::Blue, FString::Printf(TEXT("HandlePositionMessage: x: %f, y: %f, z: %f"), Message.Position.X, Message.Position.Y, Message.Position.Z));
if (!HasAuthority())
Position = Message.Position;
}