Fixing the Game View Zoom Issue in Unity
For years I've been running into a small but annoying problem in Unity: the Game window doesn't always remember its zoom level.
Sometimes after a recompile or editor refresh it gets reset or zoomed in, and instead of seeing the whole game view I end up with a cropped, zoomed-in version.
I thought this was just me at first, but there are forum threads and bug reports going back to at least 2019, all describing the same behavior.
Some people suggested changing editor layouts, locking the Game view, or adjusting aspect ratio presets - but none of those worked reliably in my case.
So I decided to take a more radical approach: write a small Editor script that automatically resets the Game view to the minimum allowed zoom level every time scripts are recompiled.
It hooks into Unity's editor events, digs into the internal GameView window with reflection, and applies the correct scale.
The script itself lives in Assets/Editor/ and once it's there, the zoom issue essentially disappears.
I've tested this fix with Unity 6.2 and it works consistently.
If you've been struggling with the same problem, give this approach a try. It's a bit of a workaround, but until Unity addresses the root cause, it provides a reliable solution and saves a lot of frustration.
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
using System.Reflection;
static class GameViewScaleToMin
{
[DidReloadScripts]
static void OnScriptsReloaded() => EditorApplication.delayCall += ScaleToMin;
[MenuItem("Tools/GameView/Scale to Min")]
static void ScaleToMin()
{
var gvType = typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView");
var gv = EditorWindow.GetWindow(gvType);
if (gv == null) { Debug.LogError("[GV] GameView not found"); return; }
var zoomField = gvType.GetField("m_ZoomArea", BindingFlags.Instance | BindingFlags.NonPublic);
var zoom = zoomField?.GetValue(gv);
if (zoom == null) { Debug.LogError("[GV] m_ZoomArea null"); return; }
var t = zoom.GetType();
// Read mins from FIELDS
float hMin = (float)(t.GetField("m_HScaleMin", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(zoom) ?? 0.5f);
float vMin = (float)(t.GetField("m_VScaleMin", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(zoom) ?? 0.5f);
float target = Mathf.Max(hMin, vMin);
// Set the new scale
var mScaleField = t.GetField("m_Scale", BindingFlags.Instance | BindingFlags.NonPublic);
mScaleField?.SetValue(zoom, new Vector2(target, target));
// Enforce & repaint
t.GetMethod("EnforceScaleAndRange", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
?.Invoke(zoom, null);
gv.Repaint();
// I am not sure if this is needed, but it doesn't hurt
EditorApplication.delayCall -= ScaleToMin;
}
}
#endif