You need to enable JavaScript to run this app. Unity 2018+(含2020)编辑器实现GameView全屏的方法及反射报错排查
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2018+(含2020)编辑器实现GameView全屏的方法及反射报错排查

Unity 2018+ 编辑器Game窗口全屏的适配方案

旧脚本报错的核心原因

  • 你在System.Object Res = GetMainGameView.Invoke (null, null);行触发的异常,本质不是Unity彻底禁用了对GetMainGameView的反射访问,而是2018及以上版本中该方法的绑定规则发生了变化:
    • 旧脚本仅匹配NonPublic | Static的方法绑定位,而部分新版Unity版本中GetMainGameView的访问修饰符被调整为公开,对应绑定参数完全无法匹配,最终反射拿到的GetMainGameView对象为null,调用空对象自然会抛出异常。
    • 旧脚本中进入编辑模式时直接gameView.Close()的逻辑,也不符合新版编辑器的窗口生命周期规则,容易触发编辑器崩溃、用户自定义布局被意外破坏。

跨版本兼容的可靠实现逻辑

  • 调整反射的绑定参数,增加兜底查找逻辑,避免反射匹配失败直接崩溃:
    System.Type gameViewType = System.Type.GetType("UnityEditor.GameView,UnityEditor");
    // 多绑定位匹配,兼容不同版本的方法可见性调整
    System.Reflection.MethodInfo getMainGameViewMethod = gameViewType.GetMethod(
        "GetMainGameView",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.Public
    );
    EditorWindow gameView = null;
    // 反射拿不到目标方法时的兜底逻辑:遍历已打开的编辑器窗口匹配GameView类型
    if (getMainGameViewMethod != null)
    {
        gameView = (EditorWindow)getMainGameViewMethod.Invoke(null, null);
    }
    else
    {
        EditorWindow[] allWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
        foreach (var win in allWindows)
        {
            if (win.GetType() == gameViewType)
            {
                gameView = win;
                break;
            }
        }
    }
    
  • 用GameView内置的全屏属性替代手动修改窗口位置、大小的逻辑,稳定性远高于旧的手动计算方式:
    switch (_playModeStateChange)
    {
        case PlayModeStateChange.EnteredPlayMode:
            // 确保GameView窗口激活显示
            gameView.Show();
            gameView.Focus();
            // 通过反射设置内置全屏属性,实现无工具栏遮挡的真全屏
            var fullScreenProp = gameViewType.GetProperty("fullScreen",
                System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Instance);
            fullScreenProp.SetValue(gameView, true, null);
            break;
        case PlayModeStateChange.EnteredEditMode:
            // 退出播放时仅恢复窗口状态,不要直接关闭窗口破坏用户布局
            var exitFullScreenProp = gameViewType.GetProperty("fullScreen",
                System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Instance);
            exitFullScreenProp.SetValue(gameView, false, null);
            break;
    }
    
  • 原脚本的菜单开关逻辑、PlayerPrefs存储状态的部分可以完全保留,不需要额外修改,仅替换上述反射调用、窗口控制的代码段即可。

实现注意事项

  • 不要手动将GameView的minSize、maxSize强制设为屏幕分辨率:在多显示器、系统显示缩放比例不为100%的场景下,固定尺寸会导致窗口错位、无法正常退出全屏。
  • 不要在进入编辑模式时直接调用gameView.Close():该操作会把用户原本停靠在编辑器布局里的GameView标签页彻底关闭,破坏自定义工作区布局,仅将全屏属性重置为false即可恢复窗口原始状态。

内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 18:06:02