using System; using System.Reflection; using UnityEditor; namespace BFEditor { public static class GameViewUtils { static object gameViewSizesInstance; static MethodInfo getGroup; static GameViewUtils() { var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType); var instanceProp = singleType.GetProperty("instance"); getGroup = sizesType.GetMethod("GetGroup"); gameViewSizesInstance = instanceProp.GetValue(null, null); } public enum GameViewSizeType { AspectRatio, FixedResolution } public static void SetSize(int index) { var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var gvWnd = EditorWindow.GetWindow(gvWndType); selectedSizeIndexProp.SetValue(gvWnd, index, null); } public static void AddCustomSize(int width, int height, string text = "") { AddCustomSize(GameViewSizeGroupType.Standalone, width, height, text); } public static void AddCustomSize(GameViewSizeGroupType sizeGroupType, int width, int height, string text) { AddCustomSize(GameViewSizeType.FixedResolution, sizeGroupType, width, height, text); } public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text) { var group = GetGroup(sizeGroupType); var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); var ctor = gvsType.GetConstructor(new Type[] { typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType"), typeof(int), typeof(int), typeof(string) }); var newGvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.FixedResolution"); if (viewSizeType == GameViewSizeType.AspectRatio) newGvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizeType.AspectRatio"); var newSize = ctor.Invoke(new object[] { newGvsType, width, height, text }); addCustomSize.Invoke(group, new object[] { newSize }); } public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text) { return FindSize(sizeGroupType, text) != -1; } public static bool SizeExists(int width, int height) { return SizeExists(GameViewSizeGroupType.Standalone, width, height); } public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height) { return FindSize(sizeGroupType, width, height) != -1; } public static int FindSize(GameViewSizeGroupType sizeGroupType, string text) { var group = GetGroup(sizeGroupType); 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]; int pren = display.IndexOf('('); if (pren != -1) display = display.Substring(0, pren - 1); if (display == text) return i; } return -1; } public static int FindSize(int width, int height) { return FindSize(GameViewSizeGroupType.Standalone, width, height); } public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height) { var group = GetGroup(sizeGroupType); var groupType = group.GetType(); var getBuiltinCount = groupType.GetMethod("GetBuiltinCount"); var getCustomCount = groupType.GetMethod("GetCustomCount"); int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null); var getGameViewSize = groupType.GetMethod("GetGameViewSize"); var gvsType = getGameViewSize.ReturnType; var widthProp = gvsType.GetProperty("width"); var heightProp = gvsType.GetProperty("height"); var indexValue = new object[1]; for (int i = 0; i < sizesCount; i++) { indexValue[0] = i; var size = getGameViewSize.Invoke(group, indexValue); int sizeWidth = (int)widthProp.GetValue(size, null); int sizeHeight = (int)heightProp.GetValue(size, null); if (sizeWidth == width && sizeHeight == height) return i; } return -1; } static object GetGroup(GameViewSizeGroupType type) { return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type }); } public static GameViewSizeGroupType GetCurrentGroupType() { var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType"); return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null); } public static void GetCurrentGameViewSize(out int width, out int height) { var t = System.Type.GetType("UnityEditor.GameView,UnityEditor"); var getMainGameView = t.GetMethod("GetMainGameView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); var res = getMainGameView.Invoke(null, null); var gameView = (UnityEditor.EditorWindow)res; var prop = gameView.GetType().GetProperty("currentGameViewSize", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var gvsize = prop.GetValue(gameView, new object[0] { }); var gvSizeType = gvsize.GetType(); height = (int)gvSizeType.GetProperty("height", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).GetValue(gvsize, new object[0] { }); width = (int)gvSizeType.GetProperty("width", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).GetValue(gvsize, new object[0] { }); } } }