Keep multiplayer options in the start menu only; free M for the world map.
The menu no longer opens in-game and will not reappear after gameplay has started. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
932157eda5
commit
7cc715cad5
@ -1,16 +1,9 @@
|
||||
# Multiplayer, Steam & Server Admin
|
||||
|
||||
## In-Game Menu (`M`)
|
||||
## Start Menu
|
||||
|
||||
Opens automatically on start and again with **M**:
|
||||
|
||||
- **Map** selection
|
||||
- **Backend**: Auto / Steam / LAN
|
||||
- **Host Port** + Max Players
|
||||
- **Find Steam** / **Find LAN**
|
||||
- **Join selected session**
|
||||
- **Connect by IP:Port**
|
||||
- **Play Solo**
|
||||
Map / Steam / LAN / IP:Port selection appears **only at game start**.
|
||||
It is not bound to a key in-game (`M` is reserved for the world map).
|
||||
|
||||
## Steam
|
||||
|
||||
|
||||
@ -32,7 +32,6 @@ A life-simulation action RPG remake inspired by Fantasy Life, built in **Unreal
|
||||
| Interact / Craft | E | X / Square |
|
||||
| Attack | LMB | RT |
|
||||
| Toggle camera (Top-Down / FP) | C | Menu |
|
||||
| Multiplayer menu | M | — |
|
||||
| Pause | Esc | Start |
|
||||
|
||||
### Pause menu shortcuts
|
||||
|
||||
@ -21,6 +21,11 @@ void UVocationGameInstance::Init()
|
||||
OnDataReady.Broadcast();
|
||||
}
|
||||
|
||||
void UVocationGameInstance::MarkGameplayStarted()
|
||||
{
|
||||
bHasEnteredGameplay = true;
|
||||
}
|
||||
|
||||
void UVocationGameInstance::InitializeDefaultData()
|
||||
{
|
||||
ItemDefinitions.Empty();
|
||||
|
||||
@ -76,7 +76,7 @@ void AVocationHUD::DrawMainHUD()
|
||||
}
|
||||
else
|
||||
{
|
||||
const FString Controls = TEXT("WASD Move | C Camera | M Multiplayer | E Interact | LMB Attack | I Save | Esc Pause");
|
||||
const FString Controls = TEXT("WASD Move | C Camera | E Interact | LMB Attack | I Save | Esc Pause");
|
||||
Canvas->DrawColor = FColor(200, 200, 200);
|
||||
Canvas->DrawText(GEngine->GetSmallFont(), Controls, 40.f * Scale, Canvas->ClipY - 60.f * Scale, Scale, Scale);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "VocationMainMenuWidget.h"
|
||||
#include "VocationSessionSubsystem.h"
|
||||
#include "VocationGameInstance.h"
|
||||
#include "Components/Button.h"
|
||||
#include "Components/ComboBoxString.h"
|
||||
#include "Components/EditableTextBox.h"
|
||||
@ -72,7 +73,7 @@ void UVocationMainMenuWidget::BuildUI()
|
||||
}
|
||||
};
|
||||
|
||||
AddToColumn(MakeLabel(WidgetTree, TEXT("Title"), TEXT("VocationLife Multiplayer")));
|
||||
AddToColumn(MakeLabel(WidgetTree, TEXT("Title"), TEXT("VocationLife — Start Menu")));
|
||||
|
||||
AddToColumn(MakeLabel(WidgetTree, TEXT("MapLabel"), TEXT("Map")));
|
||||
MapCombo = WidgetTree->ConstructWidget<UComboBoxString>(UComboBoxString::StaticClass(), TEXT("MapCombo"));
|
||||
@ -182,6 +183,22 @@ void UVocationMainMenuWidget::SetStatus(const FString& Message)
|
||||
}
|
||||
}
|
||||
|
||||
void UVocationMainMenuWidget::LeaveStartMenu()
|
||||
{
|
||||
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
||||
{
|
||||
GI->MarkGameplayStarted();
|
||||
}
|
||||
|
||||
if (APlayerController* PC = GetOwningPlayer())
|
||||
{
|
||||
PC->bShowMouseCursor = false;
|
||||
PC->SetInputMode(FInputModeGameOnly());
|
||||
}
|
||||
|
||||
RemoveFromParent();
|
||||
}
|
||||
|
||||
void UVocationMainMenuWidget::OnHostClicked()
|
||||
{
|
||||
UVocationSessionSubsystem* Sessions = GetGameInstance() ? GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>() : nullptr;
|
||||
@ -202,8 +219,8 @@ void UVocationMainMenuWidget::OnHostClicked()
|
||||
if (BackendIndex == 2) Backend = EVocationNetBackend::LAN;
|
||||
|
||||
SetStatus(TEXT("Hosting..."));
|
||||
LeaveStartMenu();
|
||||
Sessions->HostSession(MaxPlayers, Name, MapPath, Port, Backend, Backend == EVocationNetBackend::LAN);
|
||||
RemoveFromParent();
|
||||
}
|
||||
|
||||
void UVocationMainMenuWidget::OnFindSteamClicked()
|
||||
@ -235,6 +252,7 @@ void UVocationMainMenuWidget::OnJoinSelectedClicked()
|
||||
return;
|
||||
}
|
||||
SetStatus(TEXT("Joining session..."));
|
||||
LeaveStartMenu();
|
||||
Sessions->JoinSessionByIndex(Index);
|
||||
}
|
||||
}
|
||||
@ -246,8 +264,8 @@ void UVocationMainMenuWidget::OnConnectIpClicked()
|
||||
const FString IP = IpBox ? IpBox->GetText().ToString() : TEXT("127.0.0.1");
|
||||
const int32 Port = JoinPortBox ? FCString::Atoi(*JoinPortBox->GetText().ToString()) : 7777;
|
||||
SetStatus(FString::Printf(TEXT("Connecting to %s:%d ..."), *IP, Port));
|
||||
LeaveStartMenu();
|
||||
Sessions->ConnectByIP(IP, Port);
|
||||
RemoveFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,8 +275,8 @@ void UVocationMainMenuWidget::OnSoloClicked()
|
||||
{
|
||||
const int32 MapIndex = MapCombo ? MapCombo->GetSelectedIndex() : 0;
|
||||
const FString MapPath = CachedMaps.IsValidIndex(MapIndex) ? CachedMaps[MapIndex].MapPath : TEXT("/Engine/Maps/Entry");
|
||||
LeaveStartMenu();
|
||||
Sessions->TravelToMap(MapPath, false, 7777);
|
||||
RemoveFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,6 +313,6 @@ void UVocationMainMenuWidget::OnSessionJoined(bool bSuccess)
|
||||
SetStatus(bSuccess ? TEXT("Join/host ok") : TEXT("Join/host failed"));
|
||||
if (bSuccess)
|
||||
{
|
||||
RemoveFromParent();
|
||||
LeaveStartMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,10 +44,10 @@ void AVocationPlayerController::BeginPlay()
|
||||
GI->SetGraphicsPreset(GI->GetGraphicsPreset(), GI->IsRayTracingEnabled());
|
||||
}
|
||||
|
||||
// Show multiplayer menu on first load (local player only).
|
||||
// Start menu only once per game session — not reopenable in-game (M reserved for map).
|
||||
if (IsLocalController() && !IsRunningDedicatedServer())
|
||||
{
|
||||
ToggleMultiplayerMenu();
|
||||
ShowStartMenuIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,6 @@ void AVocationPlayerController::SetupInputComponent()
|
||||
InputComponent->BindKey(EKeys::F3, IE_Pressed, this, &AVocationPlayerController::ApplyHighGraphics).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::F4, IE_Pressed, this, &AVocationPlayerController::ApplyUltraGraphics).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::F5, IE_Pressed, this, &AVocationPlayerController::ApplyRayTracingGraphics).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::M, IE_Pressed, this, &AVocationPlayerController::ToggleMultiplayerMenu).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::H, IE_Pressed, this, &AVocationPlayerController::HostCoopGame).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::J, IE_Pressed, this, &AVocationPlayerController::JoinFirstFoundSession).bConsumeInput = false;
|
||||
InputComponent->BindKey(EKeys::S, IE_Pressed, this, &AVocationPlayerController::QuickSave).bConsumeInput = false;
|
||||
@ -118,13 +117,16 @@ void AVocationPlayerController::ClearInteractionPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
void AVocationPlayerController::ToggleMultiplayerMenu()
|
||||
void AVocationPlayerController::ShowStartMenuIfNeeded()
|
||||
{
|
||||
UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>();
|
||||
if (!GI || GI->HasGameplayStarted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MultiplayerMenu && MultiplayerMenu->IsInViewport())
|
||||
{
|
||||
MultiplayerMenu->RemoveFromParent();
|
||||
bShowMouseCursor = false;
|
||||
SetInputMode(FInputModeGameOnly());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -133,9 +135,8 @@ void AVocationPlayerController::ToggleMultiplayerMenu()
|
||||
{
|
||||
MultiplayerMenu->AddToViewport(100);
|
||||
bShowMouseCursor = true;
|
||||
FInputModeGameAndUI Mode;
|
||||
FInputModeUIOnly Mode;
|
||||
Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
|
||||
Mode.SetHideCursorDuringCapture(false);
|
||||
SetInputMode(Mode);
|
||||
}
|
||||
}
|
||||
@ -144,6 +145,10 @@ void AVocationPlayerController::HostCoopGame()
|
||||
{
|
||||
if (UVocationSessionSubsystem* Sessions = GetGameInstance()->GetSubsystem<UVocationSessionSubsystem>())
|
||||
{
|
||||
if (UVocationGameInstance* GI = GetGameInstance<UVocationGameInstance>())
|
||||
{
|
||||
GI->MarkGameplayStarted();
|
||||
}
|
||||
Sessions->HostSession(4, TEXT("VocationLife"), TEXT("/Engine/Maps/Entry"), 7777, EVocationNetBackend::Auto, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,13 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "VocationLife|Graphics")
|
||||
bool IsRayTracingEnabled() const { return bRayTracingEnabled; }
|
||||
|
||||
/** Once true, the start/multiplayer menu will not open again this session. */
|
||||
UFUNCTION(BlueprintCallable, Category = "VocationLife|UI")
|
||||
void MarkGameplayStarted();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "VocationLife|UI")
|
||||
bool HasGameplayStarted() const { return bHasEnteredGameplay; }
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "VocationLife")
|
||||
FOnVocationDataReady OnDataReady;
|
||||
|
||||
@ -68,4 +75,7 @@ protected:
|
||||
|
||||
UPROPERTY()
|
||||
bool bRayTracingEnabled = false;
|
||||
|
||||
UPROPERTY()
|
||||
bool bHasEnteredGameplay = false;
|
||||
};
|
||||
|
||||
@ -55,6 +55,8 @@ protected:
|
||||
UFUNCTION()
|
||||
void OnSessionJoined(bool bSuccess);
|
||||
|
||||
void LeaveStartMenu();
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UComboBoxString> MapCombo;
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ public:
|
||||
void ClearInteractionPrompt();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "VocationLife|UI")
|
||||
void ToggleMultiplayerMenu();
|
||||
void ShowStartMenuIfNeeded();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "VocationLife|Session")
|
||||
void HostCoopGame();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user