Launcher fullscreen and auto-scaled (GUI matrix, lists grow with the screen), game menu fully covered and muted, no minimize
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+45
-42
@@ -12,10 +12,18 @@ namespace MSCO
|
||||
{
|
||||
enum Page { P2P, ServerBrowser, Favorites }
|
||||
|
||||
const float Width = 760f;
|
||||
const float Height = 500f;
|
||||
const float SidebarWidth = 190f;
|
||||
const float StatusHeight = 36f;
|
||||
// Vollbild, automatisch skaliert: gebaut für RefHeight x RefWidth, vergrößert/verkleinert passend zur Auflösung
|
||||
const float RefHeight = 760f;
|
||||
const float RefWidth = 1180f;
|
||||
const float MinScale = 0.8f, MaxScale = 1.75f;
|
||||
const float SidebarWidth = 240f;
|
||||
const float StatusHeight = 40f;
|
||||
const float MaxContentWidth = 1100f;
|
||||
float vw, vh, uiScale = 1f; // virtuelle Bildschirmgröße (Einheiten vor der Skalierung)
|
||||
float contentHeight = 400f; // Höhe des Inhaltsbereichs - Listen wachsen damit
|
||||
|
||||
/// <summary>Höhe für eine Liste: was nach "reserved" für Überschriften/Knöpfe übrig bleibt.</summary>
|
||||
float ListHeight(float reserved, float min) { return Mathf.Max(min, contentHeight - reserved); }
|
||||
|
||||
|
||||
static readonly Color Background = Hex(0x17, 0x17, 0x1b);
|
||||
@@ -34,7 +42,6 @@ namespace MSCO
|
||||
Page page = Page.P2P;
|
||||
Vector2 profileScroll;
|
||||
bool quitConfirm;
|
||||
bool minimized;
|
||||
Vector2 playerScroll;
|
||||
Vector2 serverScroll;
|
||||
bool browserLoaded;
|
||||
@@ -65,8 +72,8 @@ namespace MSCO
|
||||
/// <summary>Fläche, die das Fenster gerade belegt (GUI-Koordinaten, oben = 0).</summary>
|
||||
public Rect ScreenRect { get; private set; }
|
||||
|
||||
/// <summary>Fenster offen (nicht minimiert) - dann ist das Spielmenü dahinter gesperrt.</summary>
|
||||
public bool IsOpen { get { return !minimized; } }
|
||||
/// <summary>Der Launcher füllt im Hauptmenü immer den ganzen Bildschirm - das Spielmenü dahinter ist gesperrt.</summary>
|
||||
public bool IsOpen { get { return true; } }
|
||||
|
||||
/// <summary>Ist die Maus gerade über dem Fenster bzw. der eingeklappten Leiste?</summary>
|
||||
public bool ContainsMouse()
|
||||
@@ -78,24 +85,37 @@ namespace MSCO
|
||||
public void Draw(MultiplayerManager mp)
|
||||
{
|
||||
EnsureStyles();
|
||||
uiScale = Mathf.Clamp(Mathf.Min(Screen.height / RefHeight, Screen.width / RefWidth), MinScale, MaxScale);
|
||||
vw = Screen.width / uiScale;
|
||||
vh = Screen.height / uiScale;
|
||||
ScreenRect = new Rect(0, 0, Screen.width, Screen.height);
|
||||
Matrix4x4 previous = GUI.matrix;
|
||||
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(uiScale, uiScale, 1f));
|
||||
try { DrawScaled(mp); }
|
||||
finally { GUI.matrix = previous; }
|
||||
}
|
||||
|
||||
void DrawScaled(MultiplayerManager mp)
|
||||
{
|
||||
// Undurchsichtiger Hintergrund über das ganze Spielmenü (Logo, Farbauswahl, Knöpfe ... sind dahinter verborgen)
|
||||
if (texScreen == null) texScreen = Solid(Hex(0x0d, 0x0d, 0x10));
|
||||
GUI.DrawTexture(new Rect(0, 0, vw, vh), texScreen);
|
||||
bool pendingJoin = mp.PendingJoinHost != null && !mp.IsInSession;
|
||||
bool versionWarning = mp.PendingVersionWarning != null && !mp.IsInSession;
|
||||
bool disconnected = mp.DisconnectNotice != null && !mp.IsInSession;
|
||||
// Getrennt / Neu-Verbinden: eigenes Fenster in der Bildmitte, alles andere gesperrt
|
||||
if (disconnected) { DrawPrompt(mp, false); return; }
|
||||
if (mp.IsReconnecting) { DrawPrompt(mp, true); return; }
|
||||
if (pendingJoin || versionWarning) minimized = false; // JOIN-Link / Warnung: Fenster zeigen
|
||||
if (minimized) { DrawMinimized(mp); return; }
|
||||
|
||||
var window = new Rect((Screen.width - Width) / 2f, (Screen.height - Height) / 2f, Width, Height);
|
||||
ScreenRect = window;
|
||||
UiTheme.DrawShadow(window);
|
||||
var window = new Rect(0, 0, vw, vh);
|
||||
GUI.Box(window, GUIContent.none, windowBox);
|
||||
|
||||
DrawSidebar(new Rect(window.x, window.y, SidebarWidth, Height - StatusHeight));
|
||||
DrawSidebar(new Rect(0, 0, SidebarWidth, vh - StatusHeight));
|
||||
|
||||
var content = new Rect(window.x + SidebarWidth + 32, window.y + 28,
|
||||
Width - SidebarWidth - 64, Height - StatusHeight - 52);
|
||||
// Inhalt mittig im freien Bereich, nicht beliebig breit (lesbar bleiben)
|
||||
float free = vw - SidebarWidth;
|
||||
float width = Mathf.Min(MaxContentWidth, free - 96f);
|
||||
var content = new Rect(SidebarWidth + (free - width) / 2f, 40f, width, vh - StatusHeight - 72f);
|
||||
contentHeight = content.height;
|
||||
GUILayout.BeginArea(content);
|
||||
if (versionWarning) DrawVersionWarning(mp);
|
||||
else if (pendingJoin) DrawJoinConfirm(mp);
|
||||
@@ -105,7 +125,7 @@ namespace MSCO
|
||||
else DrawServerBrowser(mp);
|
||||
GUILayout.EndArea();
|
||||
|
||||
DrawStatusBar(mp, new Rect(window.x, window.yMax - StatusHeight, Width, StatusHeight));
|
||||
DrawStatusBar(mp, new Rect(0, vh - StatusHeight, vw, StatusHeight));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- Bereiche
|
||||
@@ -238,7 +258,7 @@ namespace MSCO
|
||||
GUI.Label(new Rect(header.x + header.width * 0.62f, header.y, 70, header.height), "TYPE", headerCellStyle);
|
||||
GUI.Label(new Rect(header.x + header.width * 0.76f, header.y, 50, header.height), "PING", headerCellStyle);
|
||||
|
||||
serverScroll = GUILayout.BeginScrollView(serverScroll, GUILayout.Height(180));
|
||||
serverScroll = GUILayout.BeginScrollView(serverScroll, GUILayout.Height(ListHeight(230f, 140f)));
|
||||
if (shownError != null) GUILayout.Label(shownError, textStyle);
|
||||
if (servers.Count == 0)
|
||||
GUILayout.Label(browser.Loading ? "Loading servers..." : all.Count > 0 ? "No servers match your filters." : "No servers online right now.", textStyle);
|
||||
@@ -366,7 +386,7 @@ namespace MSCO
|
||||
GUILayout.Space(8);
|
||||
|
||||
List<Favorites.Favorite> favs = Favorites.All;
|
||||
favoritesScroll = GUILayout.BeginScrollView(favoritesScroll, GUILayout.Height(250));
|
||||
favoritesScroll = GUILayout.BeginScrollView(favoritesScroll, GUILayout.Height(ListHeight(190f, 160f)));
|
||||
if (favs.Count == 0)
|
||||
GUILayout.Label("No favorites yet. Click the heart next to a server in the Server Browser, or add one by address below.", textStyle);
|
||||
Favorites.Favorite remove = null;
|
||||
@@ -582,7 +602,7 @@ namespace MSCO
|
||||
GUILayout.BeginVertical(rowBox, GUILayout.ExpandWidth(true), GUILayout.MinHeight(150));
|
||||
GUILayout.Space(6);
|
||||
GUILayout.Label("PLAYERS " + s.Players + " / " + s.MaxPlayers, captionStyle);
|
||||
profileScroll = GUILayout.BeginScrollView(profileScroll, GUILayout.Height(130));
|
||||
profileScroll = GUILayout.BeginScrollView(profileScroll, GUILayout.Height(ListHeight(330f, 130f)));
|
||||
if (s.PlayerNames == null || s.PlayerNames.Count == 0)
|
||||
GUILayout.Label("Nobody online right now.", textStyle);
|
||||
else
|
||||
@@ -696,7 +716,7 @@ namespace MSCO
|
||||
|
||||
const float PromptWidth = 540f;
|
||||
const float PromptHeight = 270f;
|
||||
Texture2D texDim, texDanger;
|
||||
Texture2D texDim, texDanger, texScreen;
|
||||
GUIStyle promptTextStyle;
|
||||
|
||||
/// <summary>
|
||||
@@ -713,10 +733,9 @@ namespace MSCO
|
||||
promptTextStyle.wordWrap = true;
|
||||
promptTextStyle.fontSize = 15;
|
||||
}
|
||||
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), texDim);
|
||||
GUI.DrawTexture(new Rect(0, 0, vw, vh), texDim);
|
||||
|
||||
var r = new Rect((Screen.width - PromptWidth) / 2f, (Screen.height - PromptHeight) / 2f, PromptWidth, PromptHeight);
|
||||
ScreenRect = new Rect(0, 0, Screen.width, Screen.height); // Spielmenü dahinter komplett sperren
|
||||
var r = new Rect((vw - PromptWidth) / 2f, (vh - PromptHeight) / 2f, PromptWidth, PromptHeight);
|
||||
UiTheme.DrawShadow(r);
|
||||
GUI.Box(r, GUIContent.none, windowBox);
|
||||
string title = reconnecting
|
||||
@@ -809,7 +828,7 @@ namespace MSCO
|
||||
GUILayout.Space(16);
|
||||
|
||||
GUILayout.Label("PLAYERS " + mp.Players.Count + "/" + mp.SessionMaxPlayers, captionStyle);
|
||||
playerScroll = GUILayout.BeginScrollView(playerScroll, GUILayout.Height(170));
|
||||
playerScroll = GUILayout.BeginScrollView(playerScroll, GUILayout.Height(ListHeight(mp.IsHost ? 330f : 170f, 120f)));
|
||||
foreach (PlayerInfo p in mp.Players)
|
||||
{
|
||||
Rect row = GUILayoutUtility.GetRect(10, 32, GUILayout.ExpandWidth(true));
|
||||
@@ -848,25 +867,9 @@ namespace MSCO
|
||||
GUI.Box(r, GUIContent.none, sidebarBox);
|
||||
Texture2D dot = mp.IsFullyConnected ? texOnline : mp.IsInSession || mp.IsReconnecting ? texPending : texMuted;
|
||||
GUI.DrawTexture(new Rect(r.x + 18, r.y + (r.height - 8) / 2f, 8, 8), dot);
|
||||
GUI.Label(new Rect(r.x + 36, r.y, r.width - 180, r.height), mp.Status, statusStyle);
|
||||
if (GUI.Button(new Rect(r.xMax - 118, r.y + 6, 106, r.height - 12), "MINIMIZE", tabStyle))
|
||||
minimized = true;
|
||||
GUI.Label(new Rect(r.x + 36, r.y, r.width - 72, r.height), mp.Status, statusStyle);
|
||||
}
|
||||
|
||||
void DrawMinimized(MultiplayerManager mp)
|
||||
{
|
||||
var r = new Rect((Screen.width - 220) / 2f, 0, 220, 30);
|
||||
ScreenRect = r;
|
||||
UiTheme.DrawShadow(r);
|
||||
GUI.Box(r, GUIContent.none, sidebarBox);
|
||||
GUI.Box(new Rect(r.x + 10, r.yMax - 3, r.width - 20, 3), GUIContent.none, accentBox);
|
||||
Texture2D dot = mp.IsFullyConnected ? texOnline : mp.IsInSession || mp.IsReconnecting ? texPending : texMuted;
|
||||
Texture2D logo = Branding.LogoTexture;
|
||||
if (logo != null) GUI.DrawTexture(new Rect(r.x + 8, r.y + 4, 22, 22), logo);
|
||||
GUI.DrawTexture(new Rect(r.x + 36, r.y + 11, 8, 8), dot);
|
||||
if (GUI.Button(new Rect(r.x + 48, r.y, r.width - 48, r.height), "MSCO MULTIPLAYER ▾", tabStyle))
|
||||
minimized = false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- Hilfen
|
||||
|
||||
|
||||
Reference in New Issue
Block a user