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 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 15:31:05 -04:00
co-authored by Claude Opus 4.8
parent e21c6c3c44
commit 8bbc1cfac8
2 changed files with 63 additions and 19 deletions
+27 -19
View File
@@ -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<UnityEngine.Camera>())
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<UnityEngine.MonoBehaviour>())
{
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<UnityEngine.MonoBehaviou
if (lens != null)
{
var lt = lens.GetType();
object fov = null, mode = null;
object osize = null, fov = null;
foreach (var n in new[] { "OrthographicSize", "m_OrthographicSize" })
{ var f = lt.GetField(n, bf); if (f != null) { osize = f.GetValue(lens); break; } }
foreach (var n in new[] { "FieldOfView", "m_FieldOfView" })
{ var f = lt.GetField(n, bf); if (f != null) { fov = f.GetValue(lens); break; } }
foreach (var n in new[] { "ModeOverride", "m_ModeOverride" })
{ var f = lt.GetField(n, bf); if (f != null) { mode = f.GetValue(lens); break; } }
sb.AppendLine($"CM {t.Name} '{mb.name}' lensFOV={fov} modeOverride={mode} enabled={mb.enabled}");
sb.AppendLine($"CM {t.Name} '{mb.name}' lensOrthoSize={osize} lensFOV={fov} enabled={mb.enabled}");
}
else sb.AppendLine($"CM {t.Name} '{mb.name}' (no lens field) enabled={mb.enabled}");
else sb.AppendLine($"CM {t.Name} '{mb.name}' (no lens) enabled={mb.enabled}");
}
// --- uGUI canvas scalers (HUD scaling at ultrawide) ---
// --- uGUI canvas scalers: match=0 scales by WIDTH (bad at ultrawide), 1 = by HEIGHT ---
foreach (var cs in UnityEngine.Object.FindObjectsOfType<UnityEngine.UI.CanvasScaler>())
sb.AppendLine($"UI {cs.name} mode={cs.uiScaleMode} ref={cs.referenceResolution} " +
$"match={cs.matchWidthOrHeight} screenMatch={cs.screenMatchMode}");
foreach (var cv in UnityEngine.Object.FindObjectsOfType<UnityEngine.Canvas>())
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());
+36
View File
@@ -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<UnityEngine.UI.CanvasScaler>())
{
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<UnityEngine.Camera>())
{
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());