// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "GameUIPolicy.generated.h" class ULocalPlayer; class UCommonLocalPlayer; class UPrimaryGameLayout; class UGameUIManagerSubsystem; /** * */ 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) ULocalPlayer* LocalPlayer = nullptr; UPROPERTY(Transient) UPrimaryGameLayout* 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(Abstract, Blueprintable, Within = GameUIManagerSubsystem) class COMMONGAME_API UGameUIPolicy : public UObject { GENERATED_BODY() public: template static GameUIPolicyClass* GetGameUIPolicyAs(const UObject* WorldContextObject) { return Cast(GetGameUIPolicy(WorldContextObject)); } static UGameUIPolicy* GetGameUIPolicy(const UObject* WorldContextObject); public: virtual UWorld* GetWorld() const override; UGameUIManagerSubsystem* GetOwningUIManager() const; UPrimaryGameLayout* GetRootLayout(const UCommonLocalPlayer* LocalPlayer) const; ELocalMultiplayerInteractionMode GetLocalMultiplayerInteractionMode() const { return LocalMultiplayerInteractionMode; } void RequestPrimaryControl(UPrimaryGameLayout* Layout); protected: void AddLayoutToViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); void RemoveLayoutFromViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); virtual void OnRootLayoutAddedToViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); virtual void OnRootLayoutRemovedFromViewport(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); virtual void OnRootLayoutReleased(UCommonLocalPlayer* LocalPlayer, UPrimaryGameLayout* Layout); void CreateLayoutWidget(UCommonLocalPlayer* LocalPlayer); TSubclassOf GetLayoutWidgetClass(UCommonLocalPlayer* LocalPlayer); private: ELocalMultiplayerInteractionMode LocalMultiplayerInteractionMode = ELocalMultiplayerInteractionMode::PrimaryOnly; UPROPERTY(EditAnywhere) TSoftClassPtr LayoutClass; UPROPERTY(Transient) TArray RootViewportLayouts; private: void NotifyPlayerAdded(UCommonLocalPlayer* LocalPlayer); void NotifyPlayerRemoved(UCommonLocalPlayer* LocalPlayer); void NotifyPlayerDestroyed(UCommonLocalPlayer* LocalPlayer); friend class UGameUIManagerSubsystem; };