#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Cluster/IDisplayClusterClusterManager.h" #include "Cluster/DisplayClusterClusterEvent.h" #include "UserInputSync.generated.h" UCLASS() class AUserInputSync : public AActor { GENERATED_BODY() public: void BeginPlay() override; void EndPlay(const EEndPlayReason::Type EndPlayReason) override; UFUNCTION(BlueprintCallable) void OnUserInput(); void ReactOnUserInput(); private: FOnClusterEventListener ClusterEventListenerDelegate; void HandleClusterEvent(const FDisplayClusterClusterEvent& Event); }; // In UserInputSync.cpp: #include "UserInputSync.h" #include "IUniversalLogging.h" //just here to give some feedback on the user's action #include "Engine.h" #include "IDisplayCluster.h" void AUserInputSync::BeginPlay() { Super::BeginPlay(); //register the listener IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr(); if (ClusterManager && !ClusterEventListenerDelegate.IsBound()) { ClusterEventListenerDelegate = FOnClusterEventListener::CreateUObject(this, &AUserInputSync::HandleClusterEvent); ClusterManager->AddClusterEventListener(ClusterEventListenerDelegate); } //so the log shows on all slaves on screen UniLog.GetDefaultLogStream()->SetLogOnScreenOnMaster(true); UniLog.GetDefaultLogStream()->SetLogOnScreenOnSlaves(true); } void AUserInputSync::EndPlay(const EEndPlayReason::Type EndPlayReason) { //de-register the listener again IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr(); if (ClusterManager && ClusterEventListenerDelegate.IsBound()) { ClusterManager->RemoveClusterEventListener(ClusterEventListenerDelegate); } Super::EndPlay(EndPlayReason); } void AUserInputSync::ReactOnUserInput() { //some action you want to perform on all nodes, e.g.: UniLog.Log("Input received!"); } void AUserInputSync::OnUserInput() { IDisplayClusterClusterManager* const Manager = IDisplayCluster::Get().GetClusterMgr(); if (Manager) { if (Manager->IsStandalone()) { //in standalone (e.g., desktop editor play) cluster events are not executed.... ReactOnUserInput(); } else { // else create a cluster event to react to FDisplayClusterClusterEvent cluster_event; cluster_event.Name = "Some Custom Name, e.g., G pressed"; Manager->EmitClusterEvent(cluster_event, true); } } } void AUserInputSync::HandleClusterEvent(const FDisplayClusterClusterEvent& Event) { if (Event.Name == "Some Custom Name, e.g., G pressed") { //now we actually react on all cluster nodes: ReactOnUserInput(); } }