diff --git a/Content/Input/Default_IMC/IMC_General.uasset b/Content/Input/Default_IMC/IMC_General.uasset
index 4b74905bb2a24bd5cad5ddb52693c01da084dc76..8de5bc1e14890320eb9d9781c7f5c683ee22b42f 100644
Binary files a/Content/Input/Default_IMC/IMC_General.uasset and b/Content/Input/Default_IMC/IMC_General.uasset differ
diff --git a/RWTHVRToolkit.uplugin b/RWTHVRToolkit.uplugin
index 9cee822208bd6643aa5e9d370483c968cb25eb44..3629dc720c75269dace2ffe6649b067e63900e3a 100644
--- a/RWTHVRToolkit.uplugin
+++ b/RWTHVRToolkit.uplugin
@@ -27,6 +27,15 @@
 		}
 	],
 	"Plugins": [
+		{
+			"Name": "RWTHVRCluster",
+			"Enabled": true,
+			"Optional": true,
+			"SupportedTargetPlatforms": [
+				"Win64",
+				"Linux"
+			]
+		},
 		{
 			"Name": "LiveLink",
 			"Enabled": true
diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
index 5a84da66b664d3070c5c71bd6242d42f96ab6910..28eb764a59ca38694d676b5e0809c9a9622a14b1 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
@@ -16,6 +16,10 @@
 #include "Roles/LiveLinkTransformTypes.h"
 #include "Utility/RWTHVRUtilities.h"
 
+#if PLATFORM_SUPPORTS_CLUSTER
+#include "Components/DisplayClusterSceneComponentSyncParent.h"
+#endif
+
 ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
 {
 	BaseEyeHeight = 160.0f;
@@ -36,15 +40,19 @@ ARWTHVRPawn::ARWTHVRPawn(const FObjectInitializer& ObjectInitializer) : Super(Ob
 
 	LeftHand = CreateDefaultSubobject<UReplicatedMotionControllerComponent>(TEXT("Left Hand MCC"));
 	LeftHand->SetupAttachment(RootComponent);
-	
-#if 0	
+}
+void ARWTHVRPawn::BeginPlay()
+{
+	Super::BeginPlay();
+
+#if PLATFORM_SUPPORTS_CLUSTER
 	// Add an nDisplay Parent Sync Component. It syncs the parent's transform from master to clients.
 	// This is required because for collision based movement, it can happen that the physics engine
 	// for some reason acts different on the nodes, therefore leading to a potential desync when
 	// e.g. colliding with an object while moving.
-	SyncComponent =
-		CreateDefaultSubobject<UDisplayClusterSceneComponentSyncParent>(TEXT("Parent Display Cluster Sync Component"));
+	SyncComponent = NewObject<UDisplayClusterSceneComponentSyncParent>();
 	SyncComponent->SetupAttachment(RootComponent);
+	SyncComponent->RegisterComponent();
 #endif
 }
 
diff --git a/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp b/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp
index 77330f037057bdf8852c2a3b712876d5b2cd98bf..f43fc658f2d5ce7b6ca66c409d9b30583bbcc99e 100644
--- a/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp
+++ b/Source/RWTHVRToolkit/Private/Utility/RWTHVRUtilities.cpp
@@ -1,15 +1,5 @@
 #include "Utility/RWTHVRUtilities.h"
 
-#if PLATFORM_SUPPORTS_NDISPLAY
-#include "DisplayClusterConfigurationTypes.h"
-#include "DisplayClusterRootActor.h"
-#include "IDisplayCluster.h"
-#include "Cluster/IDisplayClusterClusterManager.h"
-#include "Components/DisplayClusterCameraComponent.h"
-#include "Config/IDisplayClusterConfigManager.h"
-#include "Game/IDisplayClusterGameManager.h"
-#endif
-
 #include "AudioDevice.h"
 #include "IHeadMountedDisplay.h"
 #include "IXRTrackingSystem.h"
@@ -17,6 +7,10 @@
 #include "Engine/LocalPlayer.h"
 #include "Kismet/GameplayStatics.h"
 
+#if PLATFORM_SUPPORTS_CLUSTER
+#include "Utility/RWTHVRClusterUtilities.h"
+#endif
+
 
 DEFINE_LOG_CATEGORY(Toolkit);
 
@@ -25,15 +19,6 @@ bool URWTHVRUtilities::IsDesktopMode()
 	return !IsRoomMountedMode() && !IsHeadMountedMode();
 }
 
-bool URWTHVRUtilities::IsRoomMountedMode()
-{
-#if PLATFORM_SUPPORTS_NDISPLAY
-	return IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster;
-#else
-	return false;
-#endif
-}
-
 bool URWTHVRUtilities::IsHeadMountedMode()
 {
 	// In editor builds: checks for EdEngine->IsVRPreviewActive()
@@ -41,65 +26,20 @@ bool URWTHVRUtilities::IsHeadMountedMode()
 	return FAudioDevice::CanUseVRAudioDevice();
 }
 
-bool URWTHVRUtilities::IsCave()
+bool URWTHVRUtilities::IsRoomMountedMode()
 {
-#if PLATFORM_SUPPORTS_NDISPLAY
-	if (!IsRoomMountedMode())
-		return false;
-
-	const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig();
-	return ClusterConfig->CustomParameters.Contains("Hardware_Platform")
-		&& ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("aixcave", ESearchCase::IgnoreCase);
-#else
-	return false;
+#if PLATFORM_SUPPORTS_CLUSTER
+	URWTHVRClusterUtilities::IsRoomMountedMode();
 #endif
-}
-
-bool URWTHVRUtilities::IsRolv()
-{
-#if PLATFORM_SUPPORTS_NDISPLAY
-	if (!IsRoomMountedMode())
-		return false;
-
-	const UDisplayClusterConfigurationData* ClusterConfig = IDisplayCluster::Get().GetConfigMgr()->GetConfig();
-	return ClusterConfig->CustomParameters.Contains("Hardware_Platform")
-		&& ClusterConfig->CustomParameters.Find("Hardware_Platform")->Equals("ROLV", ESearchCase::IgnoreCase);
-#else
 	return false;
-#endif
 }
 
-/* Return true on the Primary in cluster mode and in a normal desktop session. Otherwise false */
 bool URWTHVRUtilities::IsPrimaryNode()
 {
-#if PLATFORM_SUPPORTS_NDISPLAY
-	if (!IDisplayCluster::IsAvailable())
-	{
-		return true;
-	}
-	IDisplayClusterClusterManager* Manager = IDisplayCluster::Get().GetClusterMgr();
-	if (Manager == nullptr)
-	{
-		return true; // if we are not in cluster mode, we are always the primary node
-	}
-	return Manager->IsPrimary() || !Manager->IsSecondary();
-#else
-    return true;
-#endif
-}
-
-bool URWTHVRUtilities::IsSecondaryNode()
-{
-	return !IsPrimaryNode();
-}
-
-FString URWTHVRUtilities::GetNodeName()
-{
-#if PLATFORM_SUPPORTS_NDISPLAY
-	return IsRoomMountedMode() ? IDisplayCluster::Get().GetClusterMgr()->GetNodeId() : FString(TEXT("Localhost"));
-#else
-	return FString(TEXT("Localhost"));
+#if PLATFORM_SUPPORTS_CLUSTER
+	URWTHVRClusterUtilities::IsPrimaryNode();
 #endif
+	return false;
 }
 
 float URWTHVRUtilities::GetEyeDistance()
@@ -108,71 +48,7 @@ float URWTHVRUtilities::GetEyeDistance()
 	{
 		return GEngine->XRSystem->GetHMDDevice()->GetInterpupillaryDistance();
 	}
-	else
-	{
-#if PLATFORM_SUPPORTS_NDISPLAY
-		const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor();
-		return (RootActor) ? RootActor->GetDefaultCamera()->GetInterpupillaryDistance() : 0.0f;
-#else
-	    return 0.0f;
-#endif
-	}
-}
-
-EEyeStereoOffset URWTHVRUtilities::GetNodeEyeType()
-{
-#if PLATFORM_SUPPORTS_NDISPLAY
-	const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor();
-	return static_cast<EEyeStereoOffset>((RootActor)
-		                                     ? RootActor->GetDefaultCamera()->GetStereoOffset()
-		                                     : EDisplayClusterEyeStereoOffset::None);
-#else
-	return EEyeStereoOffset::None;
-#endif
-}
-
-USceneComponent* URWTHVRUtilities::GetClusterComponent(const FString& Name)
-{
-#if PLATFORM_SUPPORTS_NDISPLAY
-	const ADisplayClusterRootActor* RootActor = IDisplayCluster::Get().GetGameMgr()->GetRootActor();
-	return (RootActor) ? RootActor->GetComponentByName<USceneComponent>(Name) : nullptr;
-#else
-	return nullptr;
-#endif
-}
-
-USceneComponent* URWTHVRUtilities::GetNamedClusterComponent(const ENamedClusterComponent& Component)
-{
-	switch (Component)
-	{
-	case ENamedClusterComponent::NCC_CAVE_ORIGIN:
-		return GetClusterComponent("cave_origin");
-	case ENamedClusterComponent::NCC_CAVE_CENTER:
-		return GetClusterComponent("cave_center");
-	case ENamedClusterComponent::NCC_CAVE_LHT:
-		return GetClusterComponent("left_hand_target");
-	case ENamedClusterComponent::NCC_CAVE_RHT:
-		return GetClusterComponent("right_hand_target");
-	case ENamedClusterComponent::NCC_SHUTTERGLASSES:
-		return GetClusterComponent("shutter_glasses");
-	case ENamedClusterComponent::NCC_ROLV_ORIGIN:
-		return GetClusterComponent("rolv_origin");
-	case ENamedClusterComponent::NCC_FLYSTICK:
-		return GetClusterComponent("flystick");
-	case ENamedClusterComponent::NCC_CALIBRATIO:
-		return GetClusterComponent("calibratio");
-	case ENamedClusterComponent::NCC_TRACKING_ORIGIN:
-		USceneComponent* Result;
-		if ((Result = GetClusterComponent("cave_origin")))
-			return Result;
-		if ((Result = GetClusterComponent("rolv_origin")))
-			return Result;
-		if ((Result = GetClusterComponent("tdw_origin_floor")))
-			return Result;
-		return nullptr;
-	default:
-		return nullptr;
-	}
+	return 0;
 }
 
 void URWTHVRUtilities::ShowErrorAndQuit(UWorld* WorldContext, const FString& Message)
diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
index b171d3f1f9213744628e9c1501bc52a3248418dc..5b67bd31bd46e4187a17f1849187df5aae059beb 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
@@ -6,10 +6,6 @@
 #include "LiveLinkRole.h"
 #include "Pawn/Navigation/CollisionHandlingMovement.h"
 
-#if 0
-#include "Components/DisplayClusterSceneComponentSyncParent.h"
-#endif
-
 #include "RWTHVRPawn.generated.h"
 
 class UInputMappingContext;
@@ -29,6 +25,8 @@ class RWTHVRTOOLKIT_API ARWTHVRPawn : public APawn
 public:
 	ARWTHVRPawn(const FObjectInitializer& ObjectInitializer);
 
+	virtual void BeginPlay() override;
+
 	virtual void Tick(float DeltaSeconds) override;
 
 	virtual void NotifyControllerChanged() override;
@@ -56,7 +54,7 @@ public:
 	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Camera")
 	UCameraComponent* HeadCameraComponent;
 
-	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|Camera")
+	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn")
 	USceneComponent* SyncComponent;
 
 	// LiveLink functionality
diff --git a/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h b/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h
index e0f6d7e4e6adf0735007004cbfd9b5d0ae8064f8..ef9f3f0c6f22a8249f488cbf90bc443300ce9428 100644
--- a/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h
+++ b/Source/RWTHVRToolkit/Public/Utility/RWTHVRUtilities.h
@@ -2,7 +2,6 @@
 
 #include "CoreMinimal.h"
 #include "Kismet/BlueprintFunctionLibrary.h"
-#include "UObject/ConstructorHelpers.h"
 
 #include "RWTHVRUtilities.generated.h"
 
@@ -12,33 +11,6 @@
  */
 DECLARE_LOG_CATEGORY_EXTERN(Toolkit, Log, All);
 
-UENUM(BlueprintType)
-enum class ENamedClusterComponent : uint8
-{
-	/* CAVE Specific */
-	NCC_CAVE_ORIGIN UMETA(DisplayName = "CAVE Origin"),
-	NCC_CAVE_CENTER UMETA(DisplayName = "CAVE Center"),
-	NCC_CAVE_LHT UMETA(DisplayName = "CAVE Left Hand Target"),
-	NCC_CAVE_RHT UMETA(DisplayName = "CAVE Right Hand Target"),
-
-	/* ROLV Specific */
-	NCC_ROLV_ORIGIN UMETA(DisplayName = "ROLV Origin"),
-
-	/* Non Specific */
-	NCC_CALIBRATIO UMETA(DisplayName = "Calibratio Motion to Photon Measurement Device"),
-	NCC_SHUTTERGLASSES UMETA(DisplayName = "CAVE/ROLV/TDW Shutter Glasses"),
-	NCC_FLYSTICK UMETA(DisplayName = "CAVE/ROLV/TDW Flystick"),
-	NCC_TRACKING_ORIGIN UMETA(DisplayName = "CAVE/ROLV/TDW Origin")
-};
-
-UENUM()
-enum class EEyeStereoOffset
-{
-	None,
-	Left,
-	Right
-};
-
 UCLASS()
 class RWTHVRTOOLKIT_API URWTHVRUtilities : public UBlueprintFunctionLibrary
 {
@@ -48,37 +20,16 @@ public:
 	UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform")
 	static bool IsDesktopMode();
 	UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform")
-	static bool IsRoomMountedMode();
-	UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform")
 	static bool IsHeadMountedMode();
 	UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform")
-	static bool IsCave();
+	static bool IsRoomMountedMode();
 	UFUNCTION(BlueprintPure, Category = "DisplayCluster|Platform")
-	static bool IsRolv();
-
-	UFUNCTION(BlueprintPure, Category = "DisplayCluster")
 	static bool IsPrimaryNode();
-	UFUNCTION(BlueprintPure, Category = "DisplayCluster")
-	static bool IsSecondaryNode();
 
-	UFUNCTION(BlueprintPure, Category = "DisplayCluster")
-	static FString GetNodeName();
 	/* Distance in meters */
 	UFUNCTION(BlueprintPure, Category = "DisplayCluster")
 	static float GetEyeDistance();
 
-	UFUNCTION(BlueprintPure, Category = "DisplayCluster")
-	static EEyeStereoOffset GetNodeEyeType();
-
-	//Get Component of Display Cluster by it's name, which is specified in the nDisplay config
-	UE_DEPRECATED(5.4, "GetClusterComponent has been removed because it is obsolete.")
-	UFUNCTION(BlueprintPure, BlueprintCallable, Category = "DisplayCluster", meta = (DeprecatedFunction))
-	static USceneComponent* GetClusterComponent(const FString& Name);
-
-	UE_DEPRECATED(5.4, "GetNamedClusterComponent has been removed because it is obsolete.")
-	UFUNCTION(BlueprintPure, BlueprintCallable, Category = "DisplayCluster", meta = (DeprecatedFunction))
-	static USceneComponent* GetNamedClusterComponent(const ENamedClusterComponent& Component);
-
 	UFUNCTION(BlueprintCallable)
 	static void ShowErrorAndQuit(UWorld* WorldContext, const FString& Message);
 };
diff --git a/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs b/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs
index ba27e93d92e385c204cb2609041a7a445c756d60..a949553aaa90bd704c53e9ace2f749073a5441bf 100644
--- a/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs
+++ b/Source/RWTHVRToolkit/RWTHVRToolkit.Build.cs
@@ -50,9 +50,16 @@ public class RWTHVRToolkit : ModuleRules
 			new string[]{}
 		);
 
-		PublicDefinitions.Add(IsPluginEnabledForTarget("nDisplay", base.Target)
-			? "PLATFORM_SUPPORTS_NDISPLAY=1"
-			: "PLATFORM_SUPPORTS_NDISPLAY=0");
+		if (IsPluginEnabledForTarget("RWTHVRCluster", base.Target))
+		{
+			PrivateDependencyModuleNames.Add("RWTHVRCluster");
+			PrivateDependencyModuleNames.Add("DisplayCluster");
+			PublicDefinitions.Add("PLATFORM_SUPPORTS_CLUSTER=1");
+		}
+		else
+		{			
+			PublicDefinitions.Add("PLATFORM_SUPPORTS_CLUSTER=0");
+		}
 	}
 	
 	private static bool IsPluginEnabledForTarget(string PluginName, ReadOnlyTargetRules Target)