Skip to content

Instantly share code, notes, and snippets.

@Chillu1
Last active March 14, 2024 08:47
Show Gist options
  • Save Chillu1/4c209308dc81104776718b1735c639f7 to your computer and use it in GitHub Desktop.
Save Chillu1/4c209308dc81104776718b1735c639f7 to your computer and use it in GitHub Desktop.
FullscreenGameView utility, for automatic fullscreen on play with toggle option (Game view fullscreen in editor)
/*
MIT License
Copyright (c) 2021 Chillu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#if UNITY_EDITOR
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
/// <summary>
/// Little utility for opening a "Game" view in fullscreen. Will be opened on whatever Unity thinks is the "main"
/// monitor at the moment (or last position?). If for some reason event breaks, fullscreen windows can be closed via Alt+F4.
/// </summary>
/// <remarks>
/// Confirmed to work in Unity 2020. May work in earlier and later versions. No promises.
/// <para> Unity will automatically make a new game window if we're on a double monitor setup that we don't want (extra rendering time) </para>
/// <para> So just make that window display ex. "Display 3", so it won't render anything </para>
/// </remarks>
[InitializeOnLoad]
public static class FullscreenGameView
{
private static readonly Type gameViewType = Type.GetType("UnityEditor.GameView,UnityEditor");
private static readonly PropertyInfo showToolbarProperty =
gameViewType.GetProperty("showToolbar", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly object falseObject = false; // Only box once. This is a matter of principle.
private static EditorWindow _instance;
private static readonly bool fullscreen = true;
static FullscreenGameView()
{
EditorApplication.playModeStateChanged -= ToggleFullScreen;
if (!fullscreen)
return;
EditorApplication.playModeStateChanged += ToggleFullScreen;
}
[MenuItem("Window/General/Game (Fullscreen) %#&2", priority = 2)]
public static void Toggle()
{
ToggleFullScreen(PlayModeStateChange.EnteredPlayMode);
}
public static void ToggleFullScreen(PlayModeStateChange playModeStateChange)
{
if (playModeStateChange == PlayModeStateChange.EnteredEditMode || playModeStateChange == PlayModeStateChange.ExitingEditMode)
{
CloseGameWindow();
return;
}
if (gameViewType == null)
{
Debug.LogError("GameView type not found.");
return;
}
if (showToolbarProperty == null)
{
Debug.LogWarning("GameView.showToolbar property not found.");
}
switch (playModeStateChange)
{
case PlayModeStateChange.ExitingPlayMode:
return;
case PlayModeStateChange.EnteredPlayMode: //Used to toggle
if (CloseGameWindow())
return;
break;
}
_instance = (EditorWindow) ScriptableObject.CreateInstance(gameViewType);
showToolbarProperty?.SetValue(_instance, falseObject);
var desktopResolution = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height);
var fullscreenRect = new Rect(Vector2.zero, desktopResolution);
_instance.ShowPopup();
_instance.position = fullscreenRect;
_instance.Focus();
}
private static bool CloseGameWindow()
{
if (_instance != null)
{
_instance.Close();
_instance = null;
return true;
}
return false;
}
}
#endif
@blade32232
Copy link

Hi, love the script, I was wondering if its possible it might be possible for me to modify it to have 2-3 more windows show for a surround setup, and also how do you change which "display" each window uses.

@Chillu1
Copy link
Author

Chillu1 commented Sep 1, 2021

Hi, love the script, I was wondering if its possible it might be possible for me to modify it to have 2-3 more windows show for a surround setup, and also how do you change which "display" each window uses.

For the display you would have to do:

private static readonly PropertyInfo displayProperty = gameViewType.GetProperty("targetDisplay", BindingFlags.Instance | BindingFlags.NonPublic);
            
private static object displayNumber = 1;

//In "public static void ToggleFullScreen(PlayModeStateChange playModeStateChange)" below: "showToolbarProperty?.SetValue(_instance, falseObject);" paste:

displayProperty?.SetValue(_instance, displayNumber);

For the surround setup, you would have to make multiple _instances, instead of one. Which would break the toggling as of right now. But it's def doable (although not sure how you would move them to the correct monitors/displays).

Right now, I don't have time to implement such upgrades to the script. But maybe in 3-4 weeks if I still remember.

In case you might have problems where to place it:

#if UNITY_EDITOR

using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace TagHop.Editor
{
    /// <summary>
    /// Little utility for opening a "Game" view in fullscreen. Will be opened on whatever Unity thinks is the "main"
    /// monitor at the moment (or last position?). If for some reason event breaks, fullscreen windows can be closed via Alt+F4.
    /// </summary>
    /// <remarks>
    /// Confirmed to work in Unity 2020. May work in earlier and later versions. No promises.
    /// <para> Unity will automatically make a new game window if we're on a double monitor setup that we don't want (extra rendering time) </para>
    /// <para> So just make that window display ex. "Display 3", so it won't render anything </para>
    /// </remarks>
    [InitializeOnLoad]
    public static class FullscreenGameView
    {
        private static readonly Type gameViewType = Type.GetType("UnityEditor.GameView,UnityEditor");

        private static readonly PropertyInfo showToolbarProperty =
            gameViewType.GetProperty("showToolbar", BindingFlags.Instance | BindingFlags.NonPublic);
        private static readonly PropertyInfo displayProperty = gameViewType.GetProperty("targetDisplay", BindingFlags.Instance | BindingFlags.NonPublic);

        private static readonly object falseObject = false; // Only box once. This is a matter of principle.
        private static object displayNumber = 1;
        private static EditorWindow _instance;

        private static readonly bool fullscreen = false;

        static FullscreenGameView()
        {
            EditorApplication.playModeStateChanged -= ToggleFullScreen;
            if (!fullscreen)
                return;
            EditorApplication.playModeStateChanged += ToggleFullScreen;
        }

        [MenuItem("Window/General/Game (Fullscreen) %#&2", priority = 2)]
        public static void Toggle()
        {
            ToggleFullScreen(PlayModeStateChange.EnteredPlayMode);
        }

        public static void ToggleFullScreen(PlayModeStateChange playModeStateChange)
        {
            if (playModeStateChange == PlayModeStateChange.EnteredEditMode || playModeStateChange == PlayModeStateChange.ExitingEditMode)
            {
                CloseGameWindow();
                return;
            }

            if (gameViewType == null)
            {
                Debug.LogError("GameView type not found.");
                return;
            }

            if (showToolbarProperty == null)
            {
                Debug.LogWarning("GameView.showToolbar property not found.");
            }

            switch (playModeStateChange)
            {
                case PlayModeStateChange.ExitingPlayMode:
                    return;
                case PlayModeStateChange.EnteredPlayMode: //Used to toggle
                    if (CloseGameWindow())
                        return;
                    break;
            }

            _instance = (EditorWindow) ScriptableObject.CreateInstance(gameViewType);

            showToolbarProperty?.SetValue(_instance, falseObject);
            displayProperty?.SetValue(_instance, displayNumber);

            var desktopResolution = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height);
            var fullscreenRect = new Rect(Vector2.zero, desktopResolution);
            _instance.ShowPopup();
            _instance.position = fullscreenRect;
            _instance.Focus();
        }

        private static bool CloseGameWindow()
        {
            if (_instance != null)
            {
                _instance.Close();
                _instance = null;
                return true;
            }

            return false;
        }
    }
}
#endif

@blade32232
Copy link

blade32232 commented Sep 13, 2021

Sorry for the really late response, this helped a great deal, but I am encountering the issue of moving the windows to the correct monitors, Its too bad unity doesn't have the ability to specify which monitor a window is created on. I am thinking of using a bash script to move the window using fake keyboard shortcuts, but thats a bit of a hacky way of achieving this.

@maxDepa
Copy link

maxDepa commented Sep 15, 2021

Great job on this!
Is there a way to also hide the toolbar?

@Chillu1
Copy link
Author

Chillu1 commented Sep 24, 2021

Great job on this!
Is there a way to also hide the toolbar?

Hmm, the toolbar should by default be hidden.
I haven't tested it on a Windows machine. Maybe the perceived resolution is wrong here for you?

var desktopResolution = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height);

@maxDepa
Copy link

maxDepa commented Oct 5, 2021

Hi!
Yes, I'm using windows. When I hit play I see the toolbar disappearing but after some frames it comes back.
I will test if those values are incorrect but I think it's a problem of Unity reforcing the toolbar showing.
Thanks for your reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment