I make a server RPC to ServerLayTrap. Spawn AWTrapBase using SpawnActor. TrapBase creates a timer on BeginPlay to activate the trap and set the radius of the SphereComponent. When the overlap is called, the NetMultiCast method is called.
I run this in the editor, dedicated server, 3 clients. The two clients see the actor created and see it bouncing around. I see the message "TRAP IS ACTIVE!!! " 4 times (3 for the clients and 1 for the server). I see the messages for the NetMulticast getting triggered, but SERVER only, it only happens once.
UFUNCTION(BlueprintCallable, Reliable, Server, WithValidation)
void ServerLayTrap();
void ServerLayTrap_Implementation();
bool ServerLayTrap_Validate();
void AAWPlayerController::ServerLayTrap_Implementation()
{
FActorSpawnParameters SpawnInfo;
SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
FVector NewLocation = GetPawn()->GetActorLocation() + FVector(100.f, 100.f, 50.f);
AAWTrapBase* spawn = GetWorld()->SpawnActor<AAWTrapBase>(AAWTrapBase::StaticClass()
, NewLocation, FRotator::ZeroRotator, SpawnInfo);
if (spawn)
{
//spawn->RegisterAllComponents();
spawn->m_ShowDebugRadius = true;
UE_LOG(AWGeneralLog, Warning, TEXT("%s() has spawn trap actor"), TEXT(__FUNCTION__));
UE_LOG(AWGeneralLog, Log, TEXT("%s() trap location %s"), TEXT(__FUNCTION__), *spawn->GetActorLocation().ToString());
}
else
{
UE_LOG(AWCritErrors, Error, TEXT("%s() NO pawn"), TEXT(__FUNCTION__));
}
UE_LOG(AWGeneralLog, Log, TEXT("%s() done"), TEXT(__FUNCTION__));
}
UCLASS()
class ADVENTURERSWANTED_API AAWTrapBase : public AActor
{
}
AAWTrapBase::AAWTrapBase(const class FObjectInitializer& ObjectInitializer)
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SetReplicates(true);
SetReplicateMovement(true);
bAlwaysRelevant = true;
}
// Called when the game starts or when spawned
void AAWTrapBase::BeginPlay()
{
Super::BeginPlay();
TriggerSphere->InitSphereRadius(m_TriggerRadius);
if (HasAuthority())
{
UE_LOG(AWGeneralLog, Log, TEXT("%s() %s has authority"), TEXT(__FUNCTION__), *GetName());
SetupEffects();
}
else {
UE_LOG(AWGeneralLog, Log, TEXT("%s NO authority"), *GetName());
}
GetWorld()->GetTimerManager().SetTimer(ActivateTrapHandle, this, &AAWTrapBase::ActivateTrap, m_ActivateTrapInSeconds, false);
}
void AAWTrapBase::ActivateTrap()
{
UE_LOG(AWGeneralLog, Log, TEXT("%s TRAP IS ACTIVE!!!!!!!!!!!!!!!!! "), TEXT(__FUNCTION__));
TriggerSphere->OnComponentBeginOverlap.AddDynamic(this, &AAWTrapBase::OnTriggerBegin);
m_TrapIsActive = true;
GetWorld()->GetTimerManager().ClearTimer(ActivateTrapHandle);
}
void AAWTrapBase::OnTriggerBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
MultiCastTriggered();
}
UFUNCTION(NetMulticast, Reliable)
void MultiCastTriggered();
void MultiCastTriggered_Implementation();
void AAWTrapBase::MultiCastTriggered_Implementation()
{
//Draw debug sphere if we have activated it via the config
if (m_ShowDebugRadius)
{
UE_LOG(AWGeneralLog, Log, TEXT("NetMultiCast _triggered showdebug auth: %s"), HasAuthority() ? TEXT("YES") : TEXT("NO"));
DrawDebugSphere(GetWorld(), GetActorLocation(), m_TriggerRadius, 8, FColor::Blue, false, 30.f, 1, 2.f);
}
}