/*WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW*\ ( ( ) ) |/ \| ) ) _((_ || (c) Wanzyee Studio < wanzyeestudio.blogspot.com > || ( ( |_ _ |=n |\ /| _____)) | ! ] U \.ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ./ (_(__(S) |___*/ using UnityEditor; using System; using System.Reflection; namespace WanzyeeStudio.Editrix.Toolkit{ /// /// Helper to undock and fix current Game view size in pixel unit absolutely. /// /// /// /// Apply by clicking menu "Window/View/Fix Game View Size". /// The target window found by the order below: /// 1. Game view with mouse over. /// 2. Current focused Game view. /// 3. The main Game view. /// /// /// /// It's useful to preview the real size in Game view, pixel by pixel, not ratio scaled. /// Set window to selected size on the aspect drop-down menu, only for "Fixed Resolution". /// Use this to easily set size and save presets with the built-in feature. /// It might be incorrect if the size is too big to close even over the monitor. /// /// /// /// Note, this works by reflection to access internal classes. /// We'd try to keep it up-to-date, but can't guarantee. /// /// /* * http://answers.unity3d.com/questions/179775/ */ public static class GameViewHelper{ #region Menu /// /// Resize game view to selected fixed resolution. /// [MenuItem("Window/View/Fix Game View Size", false, 205)] public static void FixGameViewSize(){ if(FixGameViewSizeValid()) FixSize(); else throw new MissingMemberException("Some reflections invalid."); } /// /// Check if FixGameViewSize() valid, resizable window existing. /// /// true, if valid. [MenuItem("Window/View/Fix Game View Size", true)] private static bool FixGameViewSizeValid(){ EditorWindow _w; object _s; return GetResizable(out _w, out _s); } #endregion #region Fields /// /// Type of Game view window. /// private static readonly Type _windowType = Type.GetType("UnityEditor.GameView, UnityEditor"); /// /// Type of UnityEditor.GameViewSize. /// With custom setting info of game view resolution, not the displayed. /// private static readonly Type _sizeType = Type.GetType("UnityEditor.GameViewSize, UnityEditor"); /// /// Method info to get main game view. /// Reflect to UnityEditor.GameView.GetMainGameView(). /// It's a private static method, without params, return UnityEditor.GameView. /// private static readonly MethodInfo _mainMehtod = new Func(() => { if(null == _windowType) return null; var _b = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; var _m = _windowType.GetMethod("GetMainGameView", _b, null, new Type[0], null); return (_windowType == _m.ReturnType) ? _m : null; })(); /// /// Property info to get current setting of game view size. /// Reflect to UnityEditor.GameView.currentGameViewSize. /// It's a private instance property, without indexer, return UnityEditor.GameViewSize. /// private static readonly PropertyInfo _sizeProp = ( FindProperty(_windowType, "currentGameViewSize", _sizeType) ); /// /// Property info to get type of game view size, 0 as AspectRatio, 1 as FixedResolution. /// Reflect to UnityEditor.GameViewSize.sizeType. /// It's a public instance property, without indexer, return UnityEditor.GameViewSizeType. /// private static readonly PropertyInfo _sizeTypeProp = FindProperty( _sizeType, "sizeType", Type.GetType("UnityEditor.GameViewSizeType, UnityEditor") ); /// /// Property info to get width of game view size. /// Reflect to UnityEditor.GameViewSize.width. /// It's a public instance property, without indexer, return int. /// private static readonly PropertyInfo _widthProp = ( FindProperty(_sizeType, "width", typeof(int)) ); /// /// Property info to get height of game view size. /// Reflect to UnityEditor.GameViewSize.height. /// It's a public instance property, without indexer, return int. /// private static readonly PropertyInfo _heightProp = ( FindProperty(_sizeType, "height", typeof(int)) ); #endregion #region Methods /// /// Get the instance property of specific define type by name and return type. /// /// The game view size property. /// Define type. /// Name. /// Return type. private static PropertyInfo FindProperty(Type defineType, string name, Type returnType){ if(null == returnType || null == defineType) return null; var _b = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; return defineType.GetProperty(name, _b, null, returnType, new Type[0], null); } /// /// Undock and fix current game view size in pixel unit. /// Set window size as Aspect Drop-Down menu, only for fixed resolution. /// private static void FixSize(){ EditorWindow _w; object _s; if(!GetResizable(out _w, out _s)) return; var _p = _w.position; //get origin _p.width = (int)_widthProp.GetValue(_s, null); _p.height = (int)_heightProp.GetValue(_s, null) + 17; //plus control bar _w.position = _p; //first set back, make window out of dock _w.position = _p; //double set to make sure resize } /// /// Get game view and check if able to fix size. /// Check reflections first, then try to get and check values used. /// Also valid for FixedResolution only. /// /// true, if able to fix size. /// GameView Window. /// GameViewSize. private static bool GetResizable(out EditorWindow window, out object size){ window = null; size = null; if(null == _mainMehtod || null == _sizeProp) return false; if(null == _sizeTypeProp || null == _widthProp || null == _heightProp) return false; window = GetCurrent(); if(null == window) return false; size = _sizeProp.GetValue(window, null); return (null != size) && (1 == (int)_sizeTypeProp.GetValue(size, null)); } /// /// Get the current game view. /// Window with mouse over first, then focused, otherwise find main. /// /// The current window. private static EditorWindow GetCurrent(){ if(_windowType.IsInstanceOfType(EditorWindow.mouseOverWindow)) return EditorWindow.mouseOverWindow; else if(_windowType.IsInstanceOfType(EditorWindow.focusedWindow)) return EditorWindow.focusedWindow; else return _mainMehtod.Invoke(null, null) as EditorWindow; } #endregion } }