前一段项目中有个需求要求点击按钮后横屏切换为竖屏,在移动设备上设置Screen.orientation = ScreenOrientation.PortraitUpsideDown;就转过来了。但是在编辑器下转不过来。下面通过反射的方法改变编辑器窗口分辨率。
1 #if UNITY_EDITOR 2 using System; 3 using System.Reflection; 4 using UnityEditor; 5 using UnityEngine; 6 7 public static class GameViewUtils 8 { 9 static object gameViewSizesInstance; 10 static MethodInfo getGroup; 11 12 static GameViewUtils() 13 { 14 // gameViewSizesInstance = ScriptableSingleton<GameViewSizes>.instance; 15 var sizesType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSizes"); 16 var singleType = typeof(ScriptableSingleton<>).MakeGenericType(sizesType); 17 var instanceProp = singleType.GetProperty("instance"); 18 getGroup = sizesType.GetMethod("GetGroup"); 19 gameViewSizesInstance = instanceProp.GetValue(null, null); 20 } 21 22 public enum GameViewSizeType 23 { 24 AspectRatio, FixedResolution 25 } 26 27 //[MenuItem("Test/AddSize")] 28 //public static void AddTestSize() 29 //{ 30 // AddCustomSize(GameViewSizeType.AspectRatio, GameViewSizeGroupType.Standalone, 123, 456, "Test size"); 31 //} 32 33 //[MenuItem("Test/SizeTextQuery")] 34 //public static void SizeTextQueryTest() 35 //{ 36 // Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "Test size")); 37 //} 38 39 //[MenuItem("Test/Query16:9Test")] 40 //public static void WidescreenQueryTest() 41 //{ 42 // Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "16:9")); 43 //} 44 45 //[MenuItem("Test/Set16:9")] 46 //public static void SetWidescreenTest() 47 //{ 48 // SetSize(FindSize(GameViewSizeGroupType.Standalone, "16:9")); 49 //} 50 51 //[MenuItem("Test/SetTestSize")] 52 //public static void SetTestSize() 53 //{ 54 // int idx = FindSize(GameViewSizeGroupType.Standalone, 123, 456); 55 // if (idx != -1) 56 // SetSize(idx); 57 //} 58 59 public static void SetSize(int index) 60 { 61 var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView"); 62 var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex", 63 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 64 var gvWnd = EditorWindow.GetWindow(gvWndType); 65 selectedSizeIndexProp.SetValue(gvWnd, index, null); 66 } 67 68 [MenuItem("Test/SizeDimensionsQuery")] 69 public static void SizeDimensionsQueryTest() 70 { 71 Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, 123, 456)); 72 } 73 74 public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text) 75 { 76 // GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupTyge); 77 // group.AddCustomSize(new GameViewSize(viewSizeType, width, height, text); 78 79 var group = GetGroup(sizeGroupType); 80 var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); // or group.GetType(). 81 var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize"); 82 var ctor = gvsType.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(string) }); 83 var newSize = ctor.Invoke(new object[] { (int)viewSizeType, width, height, text }); 84 addCustomSize.Invoke(group, new object[] { newSize }); 85 } 86 87 public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text) 88 { 89 return FindSize(sizeGroupType, text) != -1; 90 } 91 92 public static int FindSize(GameViewSizeGroupType sizeGroupType, string text) 93 { 94 // GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType); 95 // string[] texts = group.GetDisplayTexts(); 96 // for loop... 97 98 var group = GetGroup(sizeGroupType); 99 var getDisplayTexts = group.GetType().GetMethod("GetDisplayTexts"); 100 var displayTexts = getDisplayTexts.Invoke(group, null) as string[]; 101 for (int i = 0; i < displayTexts.Length; i++) 102 { 103 string display = displayTexts[i]; 104 // the text we get is "Name (W:H)" if the size has a name, or just "W:H" e.g. 16:9 105 // so if we're querying a custom size text we substring to only get the name 106 // You could see the outputs by just logging 107 // Debug.Log(display); 108 int pren = display.IndexOf('('); 109 if (pren != -1) 110 display = display.Substring(0, pren - 1); // -1 to remove the space that's before the prens. This is very implementation-depdenent 111 if (display == text) 112 return i; 113 } 114 return -1; 115 } 116 117 public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height) 118 { 119 return FindSize(sizeGroupType, width, height) != -1; 120 } 121 122 public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height) 123 { 124 // goal: 125 // GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType); 126 // int sizesCount = group.GetBuiltinCount() + group.GetCustomCount(); 127 // iterate through the sizes via group.GetGameViewSize(int index) 128 129 var group = GetGroup(sizeGroupType); 130 var groupType = group.GetType(); 131 var getBuiltinCount = groupType.GetMethod("GetBuiltinCount"); 132 var getCustomCount = groupType.GetMethod("GetCustomCount"); 133 int sizesCount = (int)getBuiltinCount.Invoke(group, null) + (int)getCustomCount.Invoke(group, null); 134 var getGameViewSize = groupType.GetMethod("GetGameViewSize"); 135 var gvsType = getGameViewSize.ReturnType; 136 var widthProp = gvsType.GetProperty("width"); 137 var heightProp = gvsType.GetProperty("height"); 138 var indexValue = new object[1]; 139 for (int i = 0; i < sizesCount; i++) 140 { 141 indexValue[0] = i; 142 var size = getGameViewSize.Invoke(group, indexValue); 143 int sizeWidth = (int)widthProp.GetValue(size, null); 144 int sizeHeight = (int)heightProp.GetValue(size, null); 145 if (sizeWidth == width && sizeHeight == height) 146 return i; 147 } 148 return -1; 149 } 150 151 static object GetGroup(GameViewSizeGroupType type) 152 { 153 return getGroup.Invoke(gameViewSizesInstance, new object[] { (int)type }); 154 } 155 156 //[MenuItem("Test/LogCurrentGroupType")] 157 //public static void LogCurrentGroupType() 158 //{ 159 // Debug.Log(GetCurrentGroupType()); 160 //} 161 public static GameViewSizeGroupType GetCurrentGroupType() 162 { 163 var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType"); 164 return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null); 165 } 166 public static void switchOrientation() 167 { 168 int width = Screen.height; 169 int height = Screen.width; 170 int index = FindSize(GetCurrentGroupType(), width, height); 171 if (index == -1) 172 { 173 AddCustomSize(GameViewSizeType.FixedResolution, GetCurrentGroupType(), width, height, ""); 174 index = FindSize(GetCurrentGroupType(), width, height); 175 } 176 if (index != -1) 177 { 178 SetSize(index); 179 } 180 else 181 { 182 Debug.LogError("switchOrientation failed, can not find or add resoulution for " + width.ToString() + "*" + height.ToString()); 183 } 184 } 185 } 186 #endif