うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】UnityEditor の中心座標を取得する

f:id:hacchi_man:20201201002541p:plain:w300

UnityEditor の中心に EditorWindow を表示させるためには、MainWindow の座標を取得することで可能になる

が MainWindow の情報は public な訳もなく、Reflection を利用して、MainWindow 探し
その位置を取得することで中心位置を知ることができる

コード

using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
 
public static class EditorWindowExtensions
{
    /// <summary>
    /// MainWindowの真ん中へ表示する
    /// </summary>
    public static void ToCenter(this EditorWindow self)
    {
        var mainWindowRect = GetMainWindowPosition();
        var pos = self.position;
        pos.x = mainWindowRect.x + (mainWindowRect.width - pos.width) * 0.5f;
        pos.y = mainWindowRect.y + (mainWindowRect.height - pos.height) * 0.5f;
        self.position = pos;
    }
 
    private static Rect GetMainWindowPosition()
    {
        var windowType = AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(a => a.GetTypes())
            .Where(t => t.IsSubclassOf(typeof(ScriptableObject)))
            .FirstOrDefault(t => t.Name == "ContainerWindow");
 
        if (windowType == null)
            return Rect.zero;
 
        var showModeField = windowType.GetField("m_ShowMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var positionProperty = windowType.GetProperty("position", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
 
        if (showModeField == null || positionProperty == null)
            return Rect.zero;
 
        foreach (var window in Resources.FindObjectsOfTypeAll(windowType))
        {
            var showMode = (int) showModeField.GetValue(window);
            if (showMode == 4)
            {
                return (Rect) positionProperty.GetValue(window, null);
            }
        }
 
        return Rect.zero;
    }
}

サンプル

Window を表示するときに呼び出したり、ボタンを押すことで中心に移動するサンプル

using UnityEditor;
using UnityEngine;
 
public class SampleEditorWindow : EditorWindow
{
    [MenuItem("Tools/Show")]
    private static void ShowWindow()
    {
        var window = GetWindow<SampleEditorWindow>();
        window.ToCenter();
        window.Show();
    }
 
    private void OnGUI()
    {
        if (GUILayout.Button("ToCenter"))
        {
            this.ToCenter();
        }
    }
}