Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to change game window resoltuion (width, height) in editor mode programmatically

Discussion in 'Scripting' started by drazicm, Nov 5, 2021.

  1. drazicm

    drazicm

    Joined:
    Sep 28, 2021
    Posts:
    4
    Hello guys!

    I want to automatizes lot of things without any use of the graphical interface and in my routine in need to manualy setup the resolution size (width and height) of the game windows as you can see bellow :


    So i want to know witch API should I communicate with ?

    I have already looked at :
    • PlayerSettings (but what i understand is that those parameters are for the build, does not want to work with Unity Editor)
      • defaultScreenHeight
      • defaultScreenWidth
      • defaultWebScreenHeight
      • defaultWebScreenWidth
    • EditorWindow (seem to be to genral i want to update only the game/PlayScene window)

    thx in advance!
     

    Attached Files:

  2. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,907
    The bad news is that there is no API. These things aren't publicly available. The good news is, you can still make it happen. There are some example here. Since it is a closed, private API, it may not work out of the box, then you will need to change those scripts. It is for sure that you need to juggle with some reflection.
     
    drazicm likes this.
  3. drazicm

    drazicm

    Joined:
    Sep 28, 2021
    Posts:
    4
    I found out a thread that explain the same problem here :
    https://answers.unity.com/questions/956123/add-and-select-game-view-resolution.html

    But I will upload the code that work for me here due to unity version complication (it's basicaly a merge from other people code found at link, i just added a AddAndSelectCustomSize static function)

    My unity version : 2019.4

    create a GameViewUtils.cs :
    Code (CSharp):
    1. using System;
    2. using System.Reflection;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. public static class GameViewUtils
    7. {
    8.     static object gameViewSizesInstance;
    9.     static MethodInfo getGroup;
    10.  
    11.     static GameViewUtils()
    12.     {
    13.         // gameViewSizesInstance  = ScriptableSingleton<GameViewSizes>.instance;
    14.         var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes");
    15.         var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType);
    16.         var instanceProp = singleType.GetProperty("instance");
    17.         getGroup = sizesType.GetMethod("GetGroup");
    18.         gameViewSizesInstance = instanceProp.GetValue(null, null);
    19.     }
    20.  
    21.     public enum GameViewSizeType
    22.     {
    23.         AspectRatio, FixedResolution
    24.     }
    25.  
    26.     [MenuItem("Test/AddSize")]
    27.     public static void AddTestSize()
    28.     {
    29.         AddCustomSize(GameViewSizeType.AspectRatio, GameViewSizeGroupType.Standalone, 123, 456, "Test size");
    30.     }
    31.  
    32.     [MenuItem("Test/SizeTextQuery")]
    33.     public static void SizeTextQueryTest()
    34.     {
    35.         Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "Test size"));
    36.     }
    37.  
    38.     [MenuItem("Test/Query16:9Test")]
    39.     public static void WidescreenQueryTest()
    40.     {
    41.         Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "16:9"));
    42.     }
    43.  
    44.     [MenuItem("Test/Set16:9")]
    45.     public static void SetWidescreenTest()
    46.     {
    47.         SetSize(FindSize(GameViewSizeGroupType.Standalone, "16:9"));
    48.     }
    49.  
    50.     [MenuItem("Test/SetTestSize")]
    51.     public static void SetTestSize()
    52.     {
    53.         int idx = FindSize(GameViewSizeGroupType.Standalone, 123, 456);
    54.         if (idx != -1)
    55.             SetSize(idx);
    56.     }
    57.  
    58.     public static void SetSize(int index)
    59.     {
    60.         var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
    61.         var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex",
    62.                 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
    63.         var gvWnd = EditorWindow.GetWindow(gvWndType);
    64.         selectedSizeIndexProp.SetValue(gvWnd, index, null);
    65.     }
    66.  
    67.     [MenuItem("Test/SizeDimensionsQuery")]
    68.     public static void SizeDimensionsQueryTest()
    69.     {
    70.         Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, 123, 456));
    71.     }
    72.  
    73.     public static void AddAndSelectCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text)
    74.     {
    75.         AddCustomSize(viewSizeType, sizeGroupType, width, height, text);
    76.         int idx = GameViewUtils.FindSize(GameViewSizeGroupType.Standalone, width, height);
    77.         GameViewUtils.SetSize(idx);
    78.     }
    79.  
    80.     public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text)
    81.     {
    82.         var group = GetGroup(sizeGroupType);
    83.         var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); // or group.GetType().
    84.         var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");
    85.         string assemblyName = "UnityEditor.dll";
    86.         Assembly assembly = Assembly.Load(assemblyName);
    87.         Type gameViewSize = assembly.GetType("UnityEditor.GameViewSize");
    88.         Type gameViewSizeType = assembly.GetType("UnityEditor.GameViewSizeType");
    89.         ConstructorInfo ctor = gameViewSize.GetConstructor(new Type[]
    90.             {
    91.                  gameViewSizeType,
    92.                  typeof(int),
    93.                  typeof(int),
    94.                  typeof(string)
    95.             });
    96.         var newSize = ctor.Invoke(new object[] { (int)viewSizeType, width, height, text });
    97.         addCustomSize.Invoke(group, new object[] { newSize });
    98.     }
    99.  
    100.     public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text)
    101.     {
    102.         return FindSize(sizeGroupType, text) != -1;
    103.     }
    104.  
    105.     public static int FindSize(GameViewSizeGroupType sizeGroupType, string text)
    106.     {
    107.         // GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType);
    108.         // string[] texts = group.GetDisplayTexts();
    109.         // for loop...
    110.  
    111.         var group = GetGroup(sizeGroupType);
    112.         var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts");
    113.         var displayTexts = getDisplayTexts.Invoke(group, null) as string[];
    114.         for (int i = 0; i < displayTexts.Length; i++)
    115.         {
    116.             string display = displayTexts[i];
    117.             // the text we get is "Name (W:H)" if the size has a name, or just "W:H" e.g. 16:9
    118.             // so if we're querying a custom size text we substring to only get the name
    119.             // You could see the outputs by just logging
    120.             // Debug.Log(display);
    121.             int pren = display.IndexOf('(');
    122.             if (pren != -1)
    123.                 display = display.Substring(0, pren - 1); // -1 to remove the space that's before the prens. This is very implementation-depdenent
    124.             if (display == text)
    125.                 return i;
    126.         }
    127.         return -1;
    128.     }
    129.  
    130.     public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height)
    131.     {
    132.         return FindSize(sizeGroupType, width, height) != -1;
    133.     }
    134.  
    135.     public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height)
    136.     {
    137.         // goal:
    138.         // GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType);
    139.         // int sizesCount = group.GetBuiltinCount() + group.GetCustomCount();
    140.         // iterate through the sizes via group.GetGameViewSize(int index)
    141.  
    142.         var group = GetGroup(sizeGroupType);
    143.         var groupType = group.GetType();
    144.         var getBuiltinCount = groupType.GetMethod("GetBuiltinCount");
    145.         var getCustomCount = groupType.GetMethod("GetCustomCount");
    146.         int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null);
    147.         var getGameViewSize = groupType.GetMethod("GetGameViewSize");
    148.         var gvsType = getGameViewSize.ReturnType;
    149.         var widthProp = gvsType.GetProperty("width");
    150.         var heightProp = gvsType.GetProperty("height");
    151.         var indexValue = new object[1];
    152.         for (int i = 0; i < sizesCount; i++)
    153.         {
    154.             indexValue[0] = i;
    155.             var size = getGameViewSize.Invoke(group, indexValue);
    156.             int sizeWidth = (int)widthProp.GetValue(size, null);
    157.             int sizeHeight = (int)heightProp.GetValue(size, null);
    158.             if (sizeWidth == width && sizeHeight == height)
    159.                 return i;
    160.         }
    161.         return -1;
    162.     }
    163.  
    164.     static object GetGroup(GameViewSizeGroupType type)
    165.     {
    166.         return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type });
    167.     }
    168.  
    169.     [MenuItem("Test/LogCurrentGroupType")]
    170.     public static void LogCurrentGroupType()
    171.     {
    172.         Debug.Log(GetCurrentGroupType());
    173.     }
    174.     public static GameViewSizeGroupType GetCurrentGroupType()
    175.     {
    176.         var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType");
    177.         return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null);
    178.     }
    179. }
    Them I simply called my function AddAndSelectCustomSize from another script when i want to change the resolution

    Code (CSharp):
    1. GameViewUtils.AddAndSelectCustomSize(GameViewUtils.GameViewSizeType.AspectRatio, GameViewSizeGroupType.Standalone, width, height, "MySceneResolution");
     
  4. andreighinea1

    andreighinea1

    Joined:
    Mar 9, 2016
    Posts:
    2
    Thanks!
    Confirmed it's working in Unity 2022.1.16f1 as well.
     
  5. sewer_cvlt

    sewer_cvlt

    Joined:
    May 28, 2015
    Posts:
    3
    This also works in Unity 2022.3.12f1

    But, I'm trying to figure out something else.
    I need to capture bunch of screenshot for Unity editor, fur purpose of browser game that doesn't run on Unity at all. I just need various images of various sizes, and they can vary. Right now, with GameViewUtils I need to add custom size every time, and after few iterations it clutters list. I don't need to add custom sizes at all, all I need is just to manipulate game windows size on the fly. Is it possible at all?
     
  6. Slock20969

    Slock20969

    Joined:
    Nov 18, 2015
    Posts:
    15
    Unbelievably helpful, thank you! Worked great in 2021.3.15f1
     
  7. ignarmezh

    ignarmezh

    Joined:
    Mar 23, 2017
    Posts:
    53
    Did you find the answer?