268 lines
10 KiB
C#
268 lines
10 KiB
C#
#if UNITY_EDITOR
|
|
using GameCore;
|
|
using System;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using static GlobalUtils;
|
|
|
|
public static class GameViewUtils
|
|
{
|
|
static object gameViewSizesInstance;
|
|
static MethodInfo getGroup;
|
|
static MethodInfo snapZoom;
|
|
static MethodInfo updateZoom;
|
|
|
|
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);
|
|
|
|
var viewType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
|
|
|
|
snapZoom = viewType.GetMethod("SnapZoom", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
updateZoom = viewType.GetMethod("UpdateZoomAreaAndParent", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
}
|
|
|
|
public enum GameViewSizeType
|
|
{
|
|
AspectRatio, FixedResolution
|
|
}
|
|
|
|
//[MenuItem("Test/AddSize")]
|
|
//public static void AddTestSize()
|
|
//{
|
|
// AddCustomSize(GameViewSizeType.AspectRatio, GameViewSizeGroupType.Standalone, 123, 456, "Test size");
|
|
//}
|
|
|
|
//[MenuItem("Test/SizeTextQuery")]
|
|
//public static void SizeTextQueryTest()
|
|
//{
|
|
// Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "Test size"));
|
|
//}
|
|
|
|
//[MenuItem("Test/Query16:9Test")]
|
|
//public static void WidescreenQueryTest()
|
|
//{
|
|
// Debug.Log(SizeExists(GameViewSizeGroupType.Standalone, "16:9"));
|
|
//}
|
|
|
|
//[MenuItem("Test/Set16:9")]
|
|
//public static void SetWidescreenTest()
|
|
//{
|
|
// SetSize(FindSize(GameViewSizeGroupType.Standalone, "16:9"));
|
|
//}
|
|
|
|
//[MenuItem("Test/SetTestSize")]
|
|
//public static void SetTestSize()
|
|
//{
|
|
// int idx = FindSize(GameViewSizeGroupType.Standalone, 123, 456);
|
|
// if (idx != -1)
|
|
// SetSize(idx);
|
|
//}
|
|
|
|
// Set Game View windows resolution index
|
|
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);
|
|
|
|
// Update zoom to make sure minScale is reflect the right value
|
|
updateZoom.Invoke(gvWnd, null);
|
|
|
|
var minScaleProperty = gvWndType.GetProperty("minScale", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
var set_scale = (float)minScaleProperty.GetValue(gvWnd, null);
|
|
|
|
SnapZoom(gvWnd, set_scale);
|
|
// Another way to setup game view window scale
|
|
/*var areaField = gvWndType.GetField("m_ZoomArea", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
var areaObj = areaField.GetValue(gvWnd);
|
|
var scaleField = areaObj.GetType().GetField("m_Scale", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
scaleField.SetValue(areaObj, new Vector2(set_scale, set_scale));*/
|
|
}
|
|
|
|
// Set Game View windows resolution index
|
|
public static void SetSize(int index, EditorWindow gameview_window)
|
|
{
|
|
var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
|
|
var selectedSizeIndexProp = gvWndType.GetProperty("selectedSizeIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
|
|
selectedSizeIndexProp.SetValue(gameview_window, index, null);
|
|
|
|
// Update zoom to make sure minScale is reflect the right value
|
|
updateZoom.Invoke(gameview_window, null);
|
|
|
|
var minScaleProperty = gvWndType.GetProperty("minScale", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
var set_scale = (float)minScaleProperty.GetValue(gameview_window, null);
|
|
|
|
SnapZoom(gameview_window, set_scale);
|
|
// Another way to setup game view window scale
|
|
/*var areaField = gvWndType.GetField("m_ZoomArea", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
var areaObj = areaField.GetValue(gvWnd);
|
|
var scaleField = areaObj.GetType().GetField("m_Scale", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
scaleField.SetValue(areaObj, new Vector2(set_scale, set_scale));*/
|
|
}
|
|
|
|
public static void AddCustomSize(GameViewSizeType viewSizeType, GameViewSizeGroupType sizeGroupType, int width, int height, string text)
|
|
{
|
|
// GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupTyge);
|
|
// group.AddCustomSize(new GameViewSize(viewSizeType, width, height, text);
|
|
|
|
var group = GetGroup(sizeGroupType);
|
|
var addCustomSize = getGroup.ReturnType.GetMethod("AddCustomSize"); // or group.GetType().
|
|
var gvsType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");
|
|
var ctor = gvsType.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(string) });
|
|
var newSize = ctor.Invoke(new object[] { (int)viewSizeType, width, height, text });
|
|
|
|
addCustomSize.Invoke(group, new object[] { newSize });
|
|
}
|
|
|
|
public static bool SizeExists(GameViewSizeGroupType sizeGroupType, string text)
|
|
{
|
|
return FindSize(sizeGroupType, text) != -1;
|
|
}
|
|
|
|
public static int FindSize(GameViewSizeGroupType sizeGroupType, string text)
|
|
{
|
|
// GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType);
|
|
// string[] texts = group.GetDisplayTexts();
|
|
// for loop...
|
|
|
|
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];
|
|
// the text we get is "Name (W:H)" if the size has a name, or just "W:H" e.g. 16:9
|
|
// so if we're querying a custom size text we substring to only get the name
|
|
// You could see the outputs by just logging
|
|
// Debug.Log(display);
|
|
int pren = display.IndexOf('(');
|
|
|
|
if (pren != -1)
|
|
{
|
|
display = display.Substring(0, pren - 1); // -1 to remove the space that's before the prens. This is very implementation-depdenent
|
|
}
|
|
|
|
if (display == text)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public static bool SizeExists(GameViewSizeGroupType sizeGroupType, int width, int height)
|
|
{
|
|
return FindSize(sizeGroupType, width, height) != -1;
|
|
}
|
|
|
|
public static int FindSize(GameViewSizeGroupType sizeGroupType, int width, int height)
|
|
{
|
|
// goal:
|
|
// GameViewSizes group = gameViewSizesInstance.GetGroup(sizeGroupType);
|
|
// int sizesCount = group.GetBuiltinCount() + group.GetCustomCount();
|
|
// iterate through the sizes via group.GetGameViewSize(int index)
|
|
|
|
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 });
|
|
}
|
|
|
|
static void SnapZoom(object gameviwe_window, float new_zoom)
|
|
{
|
|
snapZoom.Invoke(gameviwe_window, new object[] { new_zoom });
|
|
}
|
|
|
|
public static GameViewSizeGroupType GetCurrentGroupType()
|
|
{
|
|
var getCurrentGroupTypeProp = gameViewSizesInstance.GetType().GetProperty("currentGroupType");
|
|
return (GameViewSizeGroupType)(int)getCurrentGroupTypeProp.GetValue(gameViewSizesInstance, null);
|
|
}
|
|
|
|
public static void switchOrientation()
|
|
{
|
|
int width = Screen.height;
|
|
int height = Screen.width;
|
|
int index = FindSize(GetCurrentGroupType(), width, height);
|
|
|
|
if (index == -1)
|
|
{
|
|
AddCustomSize(GameViewSizeType.FixedResolution, GetCurrentGroupType(), width, height, "");
|
|
index = FindSize(GetCurrentGroupType(), width, height);
|
|
}
|
|
if (index != -1)
|
|
{
|
|
SetSize(index);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[GameViewUtils]switchOrientation: can not find or add resoulution for {width}x{height}");
|
|
}
|
|
}
|
|
|
|
public static ScreenType GetGameViewType(EditorWindow gameview_window)
|
|
{
|
|
var type = ScreenType.INVALID;
|
|
|
|
var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
|
|
var gameViewSizeType = typeof(Editor).Assembly.GetType("UnityEditor.GameViewSize");
|
|
var widthProp = gameViewSizeType.GetProperty("width");
|
|
var heightProp = gameViewSizeType.GetProperty("height");
|
|
|
|
var gameViewSizeProperty = gvWndType.GetProperty("currentGameViewSize", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
var gameViewSize = gameViewSizeProperty.GetValue(gameview_window, null);
|
|
int sizeWidth = (int)widthProp.GetValue(gameViewSize, null);
|
|
int sizeHeight = (int)heightProp.GetValue(gameViewSize, null);
|
|
|
|
if(sizeWidth >= sizeHeight)
|
|
{
|
|
type = ScreenType.LANDSCAPE;
|
|
}
|
|
else
|
|
{
|
|
type = ScreenType.PORTRAIT;
|
|
}
|
|
|
|
return type;
|
|
}
|
|
}
|
|
#endif
|