| | 1 | | using System; |
| | 2 | | using System.Reflection; |
| | 3 | | using UnityEditor; |
| | 4 | |
|
| | 5 | | //NOTE(Brian): Code adapted from this answer https://answers.unity.com/questions/956123/add-and-select-game-view-resolut |
| | 6 | | public static class GameViewUtils |
| | 7 | | { |
| | 8 | | static object gameViewSizesInstance; |
| | 9 | | static MethodInfo getGroup; |
| | 10 | |
|
| | 11 | | static GameViewUtils() |
| | 12 | | { |
| 1 | 13 | | var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); |
| 1 | 14 | | var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType); |
| 1 | 15 | | var instanceProp = singleType.GetProperty("instance"); |
| 1 | 16 | | getGroup = sizesType.GetMethod("GetGroup"); |
| 1 | 17 | | gameViewSizesInstance = instanceProp.GetValue(null, null); |
| 1 | 18 | | } |
| | 19 | |
|
| | 20 | | public enum GameViewSizeType |
| | 21 | | { |
| | 22 | | AspectRatio, FixedResolution |
| | 23 | | } |
| | 24 | |
|
| | 25 | | public static void SetSize(int index) |
| | 26 | | { |
| 6 | 27 | | var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); |
| | 28 | |
|
| 6 | 29 | | var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex", |
| | 30 | | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); |
| | 31 | |
|
| 6 | 32 | | var gvWnd = EditorWindow.GetWindow(gvWndType); |
| | 33 | |
|
| 6 | 34 | | selectedSizeIndexProp.SetValue(gvWnd, index, null); |
| 6 | 35 | | } |
| | 36 | |
|
| | 37 | | public static int AddOrGetCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, |
| | 38 | | { |
| 7 | 39 | | int id = FindSize(sizeGroupType, width, height); |
| | 40 | |
|
| 7 | 41 | | if (id != -1) |
| 5 | 42 | | return id; |
| | 43 | |
|
| 2 | 44 | | var group = GetGroup(sizeGroupType); |
| 2 | 45 | | var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); // or group.GetType(). |
| 2 | 46 | | var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); |
| 2 | 47 | | var enumType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"); |
| 2 | 48 | | var ctor = gvsType.GetConstructor(new Type[] { enumType, typeof(int), typeof(int), typeof(string) }); |
| 2 | 49 | | var newSize = ctor.Invoke(new object[] { (int)viewSizeType, width, height, text }); |
| 2 | 50 | | addCustomSize.Invoke(group, new object[] { newSize }); |
| | 51 | |
|
| 2 | 52 | | return FindSize(sizeGroupType, width, height); |
| | 53 | | } |
| | 54 | |
|
| | 55 | | public static void RemoveCustomSize(GameViewSizeGroupType sizeGroupType, int index) |
| | 56 | | { |
| 1 | 57 | | var group = GetGroup(sizeGroupType); |
| 1 | 58 | | var addCustomSize = getGroup.ReturnType.GetMethod("RemoveCustomSize"); |
| 1 | 59 | | addCustomSize.Invoke(group, new object[] { index }); |
| 1 | 60 | | } |
| | 61 | |
|
| 0 | 62 | | public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text) { return FindSize(sizeGroupType, tex |
| | 63 | |
|
| | 64 | | public static int FindSize(GameViewSizeGroupType sizeGroupType, string text) |
| | 65 | | { |
| 0 | 66 | | var group = GetGroup(sizeGroupType); |
| 0 | 67 | | var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts"); |
| 0 | 68 | | var displayTexts = getDisplayTexts.Invoke(group, null) as string[]; |
| 0 | 69 | | for (int i = 0; i < displayTexts.Length; i++) |
| | 70 | | { |
| 0 | 71 | | string display = displayTexts[i]; |
| | 72 | |
|
| | 73 | | // the text we get is "Name (W:H)" if the size has a name, or just "W:H" e.g. 16:9 |
| | 74 | | // so if we're querying a custom size text we substring to only get the name |
| | 75 | | // You could see the outputs by just logging |
| 0 | 76 | | int pren = display.IndexOf('('); |
| | 77 | |
|
| 0 | 78 | | if (pren != -1) |
| 0 | 79 | | display = display.Substring(0, pren - 1); // -1 to remove the space that's before the prens. This is ver |
| | 80 | |
|
| 0 | 81 | | if (display == text) |
| 0 | 82 | | return i; |
| | 83 | | } |
| 0 | 84 | | return -1; |
| | 85 | | } |
| | 86 | |
|
| 0 | 87 | | public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height) { return FindSize(sizeGrou |
| | 88 | |
|
| | 89 | | public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height) |
| | 90 | | { |
| 11 | 91 | | object group = GetGroup(sizeGroupType); |
| 11 | 92 | | var groupType = group.GetType(); |
| 11 | 93 | | var getBuiltinCount = groupType.GetMethod("GetBuiltinCount"); |
| 11 | 94 | | var getCustomCount = groupType.GetMethod("GetCustomCount"); |
| 11 | 95 | | int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null); |
| 11 | 96 | | var getGameViewSize = groupType.GetMethod("GetGameViewSize"); |
| 11 | 97 | | var gvsType = getGameViewSize.ReturnType; |
| 11 | 98 | | var widthProp = gvsType.GetProperty("width"); |
| 11 | 99 | | var heightProp = gvsType.GetProperty("height"); |
| 11 | 100 | | var indexValue = new object[1]; |
| | 101 | |
|
| 184 | 102 | | for (int i = 0; i < sizesCount; i++) |
| | 103 | | { |
| 89 | 104 | | indexValue[0] = i; |
| 89 | 105 | | var size = getGameViewSize.Invoke(group, indexValue); |
| 89 | 106 | | int sizeWidth = (int)widthProp.GetValue(size, null); |
| 89 | 107 | | int sizeHeight = (int)heightProp.GetValue(size, null); |
| | 108 | |
|
| 89 | 109 | | if (sizeWidth == width && sizeHeight == height) |
| 8 | 110 | | return i; |
| | 111 | | } |
| | 112 | |
|
| 3 | 113 | | return -1; |
| | 114 | | } |
| | 115 | |
|
| 14 | 116 | | static object GetGroup(GameViewSizeGroupType type) { return getGroup.Invoke(gameViewSizesInstance, new object[] { (i |
| | 117 | |
|
| | 118 | | public static GameViewSizeGroupType GetCurrentGroupType() |
| | 119 | | { |
| 0 | 120 | | var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType"); |
| | 121 | |
|
| 0 | 122 | | return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null); |
| | 123 | | } |
| | 124 | | } |