Files
KingshearthLegacy/Source/KingshearthLegacy/UI/Menu/MenuManagerSubsystem.cpp
T
Dolobarsch b55eda5e51 Neues Menüsystem implementiert
Ein flexibles Menüsystem wurde hinzugefügt, das ein Hauptmenü und ein In-Game-Menü umfasst. Das Hauptmenü bietet Optionen wie "Neues Spiel starten", "Optionen" und "Credits". Das In-Game-Menü ermöglicht Pausenfunktionen wie "Fortsetzen", "Optionen" und "Zum Desktop beenden".

Neue Klassen wurden eingeführt, darunter `MenuManagerSubsystem` zur Verwaltung von Menübildschirmen, `MenuScreenWidget` als Basisklasse für Menüs sowie spezifische Widgets wie `MainMenuWidget`, `InGameMenuWidget` und `OptionsMenuWidget`.

Zusätzlich wurden stilisierte Schaltflächen (`MenuButtonWidget`) und ein neuer `MenuPlayerController` für menübasierte Levels implementiert. Änderungen an `KingshearthLegacyPlayerController` ermöglichen die Steuerung des In-Game-Menüs. Binäre Assets für Menüs und UI wurden hinzugefügt.
2026-09-05 00:33:04 +02:00

119 lines
2.8 KiB
C++

#include "MenuManagerSubsystem.h"
#include "MenuScreenWidget.h"
#include "Engine/GameInstance.h"
#include "GameFramework/PlayerController.h"
#include "UObject/UObjectGlobals.h"
void UMenuManagerSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
FCoreUObjectDelegates::PreLoadMap.AddUObject(this, &UMenuManagerSubsystem::HandlePreLoadMap);
}
void UMenuManagerSubsystem::Deinitialize()
{
FCoreUObjectDelegates::PreLoadMap.RemoveAll(this);
Super::Deinitialize();
}
void UMenuManagerSubsystem::HandlePreLoadMap(const FString& MapName)
{
ClearStack();
}
UMenuScreenWidget* UMenuManagerSubsystem::PushScreen(TSubclassOf<UMenuScreenWidget> ScreenClass)
{
if (!ScreenClass)
{
return nullptr;
}
APlayerController* OwningController = GetGameInstance() ? GetGameInstance()->GetFirstLocalPlayerController() : nullptr;
if (!OwningController)
{
return nullptr;
}
UMenuScreenWidget* NewScreen = CreateWidget<UMenuScreenWidget>(OwningController, ScreenClass);
if (!NewScreen)
{
return nullptr;
}
// Hide (not just cover) whatever screen was on top - it stops rendering and stops taking
// input, rather than sitting underneath the new screen doing both pointlessly.
if (UMenuScreenWidget* PreviousTop = GetActiveScreen())
{
PreviousTop->SetVisibility(ESlateVisibility::Collapsed);
}
NewScreen->AddToPlayerScreen(static_cast<int32>(BaseZOrder + ScreenStack.Num()));
ScreenStack.Add(NewScreen);
RefreshInputMode();
return NewScreen;
}
void UMenuManagerSubsystem::PopScreen()
{
if (ScreenStack.Num() == 0)
{
return;
}
UMenuScreenWidget* TopScreen = ScreenStack.Pop();
if (TopScreen)
{
TopScreen->NotifyScreenClosing();
TopScreen->RemoveFromParent();
}
if (UMenuScreenWidget* NewTop = GetActiveScreen())
{
NewTop->SetVisibility(ESlateVisibility::Visible);
}
RefreshInputMode();
}
void UMenuManagerSubsystem::ClearStack()
{
for (UMenuScreenWidget* Screen : ScreenStack)
{
if (Screen)
{
Screen->NotifyScreenClosing();
Screen->RemoveFromParent();
}
}
ScreenStack.Reset();
RefreshInputMode();
}
UMenuScreenWidget* UMenuManagerSubsystem::GetActiveScreen() const
{
return ScreenStack.Num() > 0 ? ScreenStack.Last() : nullptr;
}
void UMenuManagerSubsystem::RefreshInputMode()
{
APlayerController* OwningController = GetGameInstance() ? GetGameInstance()->GetFirstLocalPlayerController() : nullptr;
if (!OwningController)
{
return;
}
if (UMenuScreenWidget* Top = GetActiveScreen())
{
FInputModeUIOnly InputMode;
InputMode.SetWidgetToFocus(Top->TakeWidget());
InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
OwningController->SetInputMode(InputMode);
OwningController->SetShowMouseCursor(true);
}
else
{
OwningController->SetInputMode(FInputModeGameOnly());
OwningController->SetShowMouseCursor(false);
}
}