From be89a2840e372d72c5b978acb69a875c4598ba6b Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 13 Nov 2023 10:59:41 +0000 Subject: [PATCH] Add replicated physics actor --- ReadMe.md | 1 + .../Private/StevesReplicatedPhysicsActor.cpp | 51 +++++++++++++++++++ .../Public/StevesReplicatedPhysicsActor.h | 23 +++++++++ 3 files changed, 75 insertions(+) create mode 100644 Source/StevesUEHelpers/Private/StevesReplicatedPhysicsActor.cpp create mode 100644 Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h diff --git a/ReadMe.md b/ReadMe.md index f22b4c0..93318fd 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -12,6 +12,7 @@ which makes a bunch of things better: * [Debug visualisation](https://www.stevestreeting.com/2021/09/14/ue4-editor-visualisation-helper/) * [Better DataTable Row References](https://www.stevestreeting.com/2023/10/06/a-better-unreal-datatable-row-picker/) * [Light Flicker](doc/LightFlicker.md) +* [Replicated Physics Actor](Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h) * Halton Sequence based random stream ## Examples diff --git a/Source/StevesUEHelpers/Private/StevesReplicatedPhysicsActor.cpp b/Source/StevesUEHelpers/Private/StevesReplicatedPhysicsActor.cpp new file mode 100644 index 0000000..2b6c816 --- /dev/null +++ b/Source/StevesUEHelpers/Private/StevesReplicatedPhysicsActor.cpp @@ -0,0 +1,51 @@ +// Copyright Steve Streeting +// Licensed under the MIT License (see License.txt) +#include "StevesReplicatedPhysicsActor.h" + + +AStevesReplicatedPhysicsActor::AStevesReplicatedPhysicsActor() +{ + PrimaryActorTick.bCanEverTick = false; + + bReplicates = true; + bStaticMeshReplicateMovement = true; + + const auto MeshComp = GetStaticMeshComponent(); + MeshComp->SetMobility(EComponentMobility::Movable); + MeshComp->SetCollisionObjectType(ECC_WorldDynamic); + MeshComp->bReplicatePhysicsToAutonomousProxy = true; + + // We do NOT replicate MeshComp itself! That's expensive and unnecessary + +} + +void AStevesReplicatedPhysicsActor::BeginPlay() +{ + SetReplicateMovement(true); + + const auto MeshComp = GetStaticMeshComponent(); + + // Server test, includes dedicated and listen servers + if (IsServer()) + { + // Server collision. Block all but allow pawns through + // Subclasses can change this if they like you can change t + MeshComp->SetCollisionResponseToAllChannels(ECR_Block); + MeshComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap); + MeshComp->SetSimulatePhysics(true); + } + else + { + // Ignore all collisions on client + MeshComp->SetCollisionResponseToAllChannels(ECR_Ignore); + } + + Super::BeginPlay(); +} + +bool AStevesReplicatedPhysicsActor::IsServer() const +{ + // Server test, includes dedicated and listen servers + // I prefer this to Authority test because you can't replicate objects client->server or client->client anyway + return GetWorld()->GetNetMode() < NM_Client; +} diff --git a/Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h b/Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h new file mode 100644 index 0000000..e068c6f --- /dev/null +++ b/Source/StevesUEHelpers/Public/StevesReplicatedPhysicsActor.h @@ -0,0 +1,23 @@ +// Copyright Steve Streeting +// Licensed under the MIT License (see License.txt) +#pragma once + +#include "CoreMinimal.h" +#include "Engine/StaticMeshActor.h" +#include "StevesReplicatedPhysicsActor.generated.h" + +/// A static mesh actor which is simulated on the server and replicated to clients. +/// The results will be pretty smooth on the clients due to a very specific set of settings. +/// You MUST spawn this actor ONLY on the server! +UCLASS(Blueprintable) +class STEVESUEHELPERS_API AStevesReplicatedPhysicsActor : public AStaticMeshActor +{ + GENERATED_BODY() + +public: + AStevesReplicatedPhysicsActor(); + +protected: + virtual void BeginPlay() override; + bool IsServer() const; +};