From 8bbc1cfac8eb3f5a8799b7e67c10bbd46826d6a4 Mon Sep 17 00:00:00 2001 From: ckoch Date: Tue, 21 Jul 2026 15:31:05 -0400 Subject: [PATCH] Correct Burglin' Gnomes diagnosis: camera is ORTHOGRAPHIC fieldOfView is meaningless here (reads 60 at every resolution because nothing uses it). The governing value is orthographicSize. Diagnostic now reports orthoSize plus computed visible width/height, and checks Cinemachine lens ortho size too. Also confirmed the HUD cause: CanvasScaler match=0.453 (width-biased) with a 1920x1080 reference, which balloons the HUD at 5120px wide. Added a live fix-test script to try match=1 and an orthoSize override in-game. Co-Authored-By: Claude Opus 4.8 --- tools/unity_diag.cs | 46 +++++++++++++++++++++++++----------------- tools/unity_fixtest.cs | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 tools/unity_fixtest.cs diff --git a/tools/unity_diag.cs b/tools/unity_diag.cs index b374fa1..cfcd0de 100644 --- a/tools/unity_diag.cs +++ b/tools/unity_diag.cs @@ -1,7 +1,12 @@ // UnityExplorer C# console diagnostic — paste into the C# Console tab, hit Run. -// Dumps cameras, Cinemachine lenses, and UI scalers so we can see what drives FOV -// and what breaks the HUD at ultrawide. Reflection-based so it compiles regardless -// of Cinemachine version/namespace (Unity 6 uses Unity.Cinemachine, older uses Cinemachine). +// Run once at ultrawide and once at 16:9, then compare. +// +// NOTE: Burglin' Gnomes uses an ORTHOGRAPHIC camera, so fieldOfView is meaningless. +// The governing value is orthographicSize (half the visible world HEIGHT): +// visible height = 2 * orthographicSize +// visible width = visible height * aspect +// If orthographicSize is CONSTANT across resolutions -> already Hor+ (correct). +// If it SHRINKS at wider aspect -> the game holds world-width constant (Vert- lock). var sb = new System.Text.StringBuilder(); sb.AppendLine($"SCREEN {UnityEngine.Screen.width}x{UnityEngine.Screen.height} " + @@ -9,19 +14,25 @@ sb.AppendLine($"SCREEN {UnityEngine.Screen.width}x{UnityEngine.Screen.height} " $"full={UnityEngine.Screen.fullScreenMode}"); foreach (var c in UnityEngine.Object.FindObjectsOfType()) - sb.AppendLine($"CAM {c.name} depth={c.depth} fov={c.fieldOfView:F2} aspect={c.aspect:F4} " + - $"phys={c.usePhysicalProperties} gate={c.gateFit} sensor={c.sensorSize} rect={c.rect} " + - $"ortho={c.orthographic} enabled={c.enabled}"); +{ + if (c.orthographic) + sb.AppendLine($"CAM {c.name} ORTHO size={c.orthographicSize:F4} aspect={c.aspect:F4} " + + $"=> visibleW={2f * c.orthographicSize * c.aspect:F3} visibleH={2f * c.orthographicSize:F3} " + + $"depth={c.depth} enabled={c.enabled}"); + else + sb.AppendLine($"CAM {c.name} PERSP fov={c.fieldOfView:F2} aspect={c.aspect:F4} " + + $"phys={c.usePhysicalProperties} gate={c.gateFit} depth={c.depth} enabled={c.enabled}"); +} -// --- Cinemachine (any version) via reflection --- +// --- Cinemachine (any version) via reflection: may drive ortho size each frame --- +var bf = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Instance; foreach (var mb in UnityEngine.Object.FindObjectsOfType()) { var t = mb.GetType(); if (t.FullName == null || t.FullName.IndexOf("Cinemachine", System.StringComparison.OrdinalIgnoreCase) < 0) continue; object lens = null; - var bf = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | - System.Reflection.BindingFlags.Instance; foreach (var name in new[] { "Lens", "m_Lens" }) { var p = t.GetProperty(name, bf); if (p != null) { lens = p.GetValue(mb); break; } @@ -30,22 +41,19 @@ foreach (var mb in UnityEngine.Object.FindObjectsOfType()) sb.AppendLine($"UI {cs.name} mode={cs.uiScaleMode} ref={cs.referenceResolution} " + - $"match={cs.matchWidthOrHeight} screenMatch={cs.screenMatchMode}"); - -foreach (var cv in UnityEngine.Object.FindObjectsOfType()) - sb.AppendLine($"CANV {cv.name} mode={cv.renderMode} cam={(cv.worldCamera ? cv.worldCamera.name : "none")}"); + $"match={cs.matchWidthOrHeight} screenMatch={cs.screenMatchMode} scaleFactor={cs.scaleFactor}"); UnityExplorer.ExplorerCore.Log(sb.ToString()); diff --git a/tools/unity_fixtest.cs b/tools/unity_fixtest.cs new file mode 100644 index 0000000..db068fa --- /dev/null +++ b/tools/unity_fixtest.cs @@ -0,0 +1,36 @@ +// LIVE FIX TEST — paste into UnityExplorer's C# Console while running at ultrawide. +// Applies both candidate fixes immediately so you can see the result on screen. +// Nothing is persisted: relaunching the game reverts everything. + +var log = new System.Text.StringBuilder(); + +// ---- FIX 1: HUD scaling ---------------------------------------------------- +// CanvasScaler.matchWidthOrHeight: 0 = scale by WIDTH, 1 = scale by HEIGHT. +// The game ships 0.453 (width-biased), which balloons the HUD at 5120px wide. +// Matching HEIGHT keeps the HUD the same physical size as it is at 16:9. +foreach (var cs in UnityEngine.Object.FindObjectsOfType()) +{ + log.AppendLine($"UI {cs.name}: match {cs.matchWidthOrHeight} -> 1.0"); + cs.matchWidthOrHeight = 1f; +} + +// ---- FIX 2: orthographic view width --------------------------------------- +// For an ortho camera, visible height = 2*orthographicSize and width follows +// aspect. If the game shrank orthographicSize at ultrawide, restoring the 16:9 +// value gives back the vertical view (true Hor+). +// Set TARGET_ORTHO to the size you measured at 1920x1080; leave null to only report. +float? TARGET_ORTHO = null; // e.g. 5.5f + +foreach (var c in UnityEngine.Object.FindObjectsOfType()) +{ + if (!c.orthographic) continue; + log.AppendLine($"CAM {c.name}: orthoSize={c.orthographicSize:F4} aspect={c.aspect:F4} " + + $"visibleW={2f * c.orthographicSize * c.aspect:F3} visibleH={2f * c.orthographicSize:F3}"); + if (TARGET_ORTHO.HasValue) + { + c.orthographicSize = TARGET_ORTHO.Value; + log.AppendLine($" -> forced orthoSize={TARGET_ORTHO.Value}"); + } +} + +UnityExplorer.ExplorerCore.Log(log.ToString());