// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Engine/World.h" #include "GameUIPolicy.generated.h" #define UE_API COMMONGAME_API class UCommonLocalPlayer; class UGameUIManagerSubsystem; class ULocalPlayer; class UPrimaryGameLayout; /** * */ UENUM() enum class ELocalMultiplayerInteractionMode : uint8 { // Fullscreen viewport for the primary player only, regardless of the other player's existence PrimaryOnly, // Fullscreen viewport for one player, but players can swap control over who's is displayed and who's is dormant SingleToggle, // Viewports displayed simultaneously for both players Simultaneous }; USTRUCT() struct FRootViewportLayoutInfo { GENERATED_BODY() public: UPROPERTY(Transient) TObjectPtr LocalPlayer = nullptr; UPROPERTY(Transient) TObjectPtr RootLayout = nullptr; UPROPERTY(Transient) bool bAddedToViewport = false; FRootViewportLayoutInfo() {} FRootViewportLayoutInfo(ULocalPlayer* InLocalPlayer, UPrimaryGameLayout* InRootLayout, bool bIsInViewport) : LocalPlayer(InLocalPlayer) , RootLayout(InRootLayout) , bAddedToViewport(bIsInViewport) {} bool operator==(const ULocalPlayer* OtherLocalPlayer) const { return LocalPlayer == OtherLocalPlayer; } }; UCLASS(MinimalAPI, Abstract, Blueprintable, Within = GameUIManagerSubsystem) class UGameUIPolicy : public UObject { GENERATED_BODY() public: template static GameUIPolicyClass* GetGameUIPolicyAs(const UObject* WorldContextObject) { return Cast(GetGameUIPolicy(WorldContextObject)); } static UE_API UGameUIPolicy* GetGameUIPolicy(const UObject* WorldContextObject); public: UE_API virtual UWorld* GetWorld() const override; UE_API UGameUIManagerSubsystem* GetOwningUIManager() const; UE_API UPrimaryGameLayout* GetRootLayout(const UCommonLocalPlayer* LocalPlayer) const; ELocalMultiplayerInteractionMode GetLocalMultiplayerInteractionMode() const { return LocalMultiplayerInteractionMode; } UE_API void RequestPrimaryControl(UPrimaryGameLayout* Layout); protected: UE_API void AddLayoutToViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); UE_API void RemoveLayoutFromViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); UE_API virtual void OnRootLayoutAddedToViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); UE_API virtual void OnRootLayoutRemovedFromViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); UE_API virtual void OnRootLayoutReleased(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); UE_API void CreateLayoutWidget(UCommonLocalPlayer* LocalPlayer); UE_API TSubclassOf GetLayoutWidgetClass(UCommonLocalPlayer* LocalPlayer); private: ELocalMultiplayerInteractionMode LocalMultiplayerInteractionMode = ELocalMultiplayerInteractionMode::PrimaryOnly; UPROPERTY(EditAnywhere) TSoftClassPtr LayoutClass; UPROPERTY(Transient) TArray RootViewportLayouts; private: UE_API void NotifyPlayerAdded(UCommonLocalPlayer* LocalPlayer); UE_API void NotifyPlayerRemoved(UCommonLocalPlayer* LocalPlayer); UE_API void NotifyPlayerDestroyed(UCommonLocalPlayer* LocalPlayer); friend class UGameUIManagerSubsystem; }; #undef UE_API