Skip to content

Instantly share code, notes, and snippets.

@wappenull
Last active August 20, 2024 06:38
Show Gist options
  • Save wappenull/668a492c80f7b7fda0f7c7f42b3ae0b0 to your computer and use it in GitHub Desktop.
Save wappenull/668a492c80f7b7fda0f7c7f42b3ae0b0 to your computer and use it in GitHub Desktop.
Unity Editor Setting game view resolution by shortcut key
/*
*
* Script to use ALT+1 ALT+2 ALT+3 for setting gameview resolution.
* If shortcut fail (such as 1280x720) you must add it manually in gameview dropdown first.
*
* Author: Wappen
*
* https://gist.github.com/wappenull/668a492c80f7b7fda0f7c7f42b3ae0b0
*
* Revision:
* - Thanks amirhakimnejad (https://gist.github.com/amirhakimnejad) add handling to mobile platform game view.
*
*/
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEditor.ShortcutManagement;
namespace Wappen.Editor
{
public static class GameViewSizeShortcut
{
[Shortcut( "Wappen/Switch Game view to 720p", KeyCode.Alpha1, ShortcutModifiers.Alt )]
static void _To720( )
{
switch( GameViewUtils.GetCurrentGroupType( ) )
{
default:
GameViewUtils.TrySetSize( "1280x720" );
break;
case GameViewSizeGroupType.Android:
// On Android, this will hit any resoulution that has "1280x720" word on it
// You might want to change these to target resolution you want
// Like either "1280x720 Portrait" "1280x720 Landscape"
// (Language might be localized in each editor locale, I wont hardcode it here)
GameViewUtils.TrySetSize( "1280x720" );
break;
case GameViewSizeGroupType.iOS:
// On iOS, see in your editor how the exact resolution name is written
// And edit this
GameViewUtils.TrySetSize( "iPad 2" );
break;
}
}
[Shortcut( "Wappen/Switch Game view to 1080p", KeyCode.Alpha2, ShortcutModifiers.Alt )]
static void _To1080( )
{
switch( GameViewUtils.GetCurrentGroupType( ) )
{
default:
GameViewUtils.TrySetSize( "1920x1080" );
break;
case GameViewSizeGroupType.Android:
GameViewUtils.TrySetSize( "1920x1080" );
break;
case GameViewSizeGroupType.iOS:
GameViewUtils.TrySetSize( "iPadPro" ); // Change to anything you want
break;
}
}
[Shortcut( "Wappen/Switch Game view to 1440p", KeyCode.Alpha3, ShortcutModifiers.Alt )]
static void _To1440( )
{
switch( GameViewUtils.GetCurrentGroupType( ) )
{
default:
GameViewUtils.TrySetSize( "2560x1440" );
break;
case GameViewSizeGroupType.Android:
GameViewUtils.TrySetSize( "2560x1440" );
break;
case GameViewSizeGroupType.iOS:
GameViewUtils.TrySetSize( "iPhone XS" ); // Change to anything you want
break;
}
}
}
// From https://answers.unity.com/questions/956123/add-and-select-game-view-resolution.html
// https://www.programmersought.com/article/8025486338/
public static class GameViewUtils
{
static object s_GameViewSizes_instance;
static Type s_GameViewType;
static MethodInfo s_GameView_SizeSelectionCallback;
static Type s_GameViewSizesType;
static MethodInfo s_GameViewSizes_GetGroup;
static Type s_GameViewSizeSingleType;
static GameViewUtils( )
{
s_GameViewType = typeof( UnityEditor.Editor ).Assembly.GetType( "UnityEditor.GameView" );
s_GameView_SizeSelectionCallback = s_GameViewType.GetMethod( "SizeSelectionCallback", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
// gameViewSizesInstance = ScriptableSingleton<GameViewSizes>.instance;
s_GameViewSizesType = typeof( UnityEditor.Editor ).Assembly.GetType( "UnityEditor.GameViewSizes" );
s_GameViewSizeSingleType = typeof( ScriptableSingleton<> ).MakeGenericType( s_GameViewSizesType );
s_GameViewSizes_GetGroup = s_GameViewSizesType.GetMethod( "GetGroup" );
var instanceProp = s_GameViewSizeSingleType.GetProperty("instance");
s_GameViewSizes_instance = instanceProp.GetValue( null, null );
}
/// <summary>
/// Try to find and set game view size to specified query.
/// Size must be already exists in game view setting.
/// You must send the right game view (your current platform) in order to get the right result.
/// </summary>
/// <param name="sizeText">Query string such as 1280x720 or 16:9</param>
public static bool TrySetSize( string sizeText )
{
GameViewSizeGroupType currentGroup = GetCurrentGroupType( );
int foundIndex = FindSize( currentGroup, sizeText );
if( foundIndex < 0 )
{
UnityEngine.Debug.LogError( $"Size {sizeText} was not found in game view settings" );
return false;
}
SetSizeIndex( foundIndex );
return true;
}
/// <summary>
/// Set current gameview size to target resolution index.
/// Index must be known beforehand.
/// </summary>
public static void SetSizeIndex( int index )
{
// Calling GameView.SizeSelectionCallback will also auto focus game view,
// We will restore focus if it is something else
EditorWindow currentWindow = EditorWindow.focusedWindow;
SceneView lastSceneView = SceneView.lastActiveSceneView;
EditorWindow gv = EditorWindow.GetWindow( s_GameViewType );
s_GameView_SizeSelectionCallback.Invoke( gv, new object[] { index, null } );
// Hack, will mock re-active scene view, in case it was active,
// Because EditorWindow.focusedWindow could now be inspector
// If scene view and game view were in same docking group,
// SizeSelectionCallback will switch to game view without knowing if user left scene view visible or not.
// - If last active was actually game view, it should be corrected by currentWindow.Focus, no problem
// - If last active is something else, like console for inspector, this will bring up scene view, should be no harm.
// Remove this out if you do not want this behavior
if( lastSceneView != null )
lastSceneView.Focus( );
if( currentWindow != null )
currentWindow.Focus( );
}
/// <summary>
/// Finding text could be fixed resoluation as WxH "1280x720"
/// or ratio like W:H "16:9"
/// </summary>
public static int FindSize( GameViewSizeGroupType sizeGroupType, string text )
{
var group = GetGroup(sizeGroupType); // class GameViewSizeGroup
var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts");
var displayTexts = getDisplayTexts.Invoke(group, null) as string[];
for( int i = 0; i < displayTexts.Length; i++ )
{
string display = displayTexts[i];
bool found = display.Contains( text );
if( found )
return i;
}
return -1;
}
static object GetGroup( GameViewSizeGroupType type )
{
return s_GameViewSizes_GetGroup.Invoke( s_GameViewSizes_instance, new object[] { (int)type } );
}
public static GameViewSizeGroupType GetCurrentGroupType( )
{
#if UNITY_STANDALONE
return GameViewSizeGroupType.Standalone;
#elif UNITY_IOS
return GameViewSizeGroupType.iOS;
#elif UNITY_ANDROID
return GameViewSizeGroupType.Android;
#endif
// Add your own
}
}
}
@amirhakimnejad
Copy link

Hey there, the code was handy for me; thank you. I've made a small change in my fork, so it simply handles different platforms. Feel free to use/pull it. Thanks.
https://gist.github.com/amirhakimnejad/ba84aee80ce5930e2125d18254b459ab

@wappenull
Copy link
Author

Hey there, the code was handy for me; thank you. I've made a small change in my fork, so it simply handles different platforms. Feel free to use/pull it. Thanks. https://gist.github.com/amirhakimnejad/ba84aee80ce5930e2125d18254b459ab

Nice, I didn't know there is separated group for mobile. I will merge it later and add a credit.

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