Skip to content

Instantly share code, notes, and snippets.

@rngtm
Last active July 11, 2018 10:38
Show Gist options
  • Select an option

  • Save rngtm/f17884dbce7488dcd010c629c72c8c86 to your computer and use it in GitHub Desktop.

Select an option

Save rngtm/f17884dbce7488dcd010c629c72c8c86 to your computer and use it in GitHub Desktop.
複数Inspectorのスクロールを同期するエディター拡張 (Unity2018.2.0f2で動作確認)
/////////////////////////////////////////////////////////////////////////
// 複数Inspectorのスクロール同期
// @ 2018 RNGTM(https://github.com/rngtm)
/////////////////////////////////////////////////////////////////////////
using System.Reflection;
using System.Linq;
using UnityEngine;
using UnityEditor;
using Type = System.Type;
public static class SyncInspectorScroll
{
const int k_UpdateInterval = 3; // updateの更新間隔(これを大きな値に設定するとエディタ負荷が下がる)
readonly static BindingFlags k_GetFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
static Type s_TypeInspectorWindow; // InspectorウィンドウのType
static int s_UpdateFrame = 0;
[InitializeOnLoadMethod]
static void OnLoad()
{
s_TypeInspectorWindow = Assembly.Load("UnityEditor.dll").GetType("UnityEditor.InspectorWindow");
EditorApplication.update += () =>
{
if (s_UpdateFrame == k_UpdateInterval)
{
s_UpdateFrame = 0;
SyncScroll();
}
else
{
s_UpdateFrame++;
}
};
}
/// <summary>
/// 現在開いているInspectorウィンドウ取得
/// </summary>
static EditorWindow[] GetInspectors()
{
return (EditorWindow[])Resources.FindObjectsOfTypeAll(s_TypeInspectorWindow);
}
/// <summary>
/// Inspectorが表示しているオブジェクトの取得 (Unity2018.2.0f2)
/// </summary>
/// <see cref="https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/Inspector/InspectorWindow.cs"/>
static Object GetInspectedObject(EditorWindow inspector)
{
return (Object)s_TypeInspectorWindow.GetMethod("GetInspectedObject", k_GetFlags).Invoke(inspector, null); // InspectorWindow.csのGetInspectedObject()を実行
}
/// <summary>
/// 複数Inspectorのスクロール同期
/// </summary>
static void SyncScroll()
{
// マウスがInspectorに乗っていなかった場合は何もしない
if (EditorWindow.mouseOverWindow == null) { return; }
if (EditorWindow.mouseOverWindow.GetType() != s_TypeInspectorWindow) { return; }
var inspectors = GetInspectors();
if (inspectors.Length <= 1) { return; }
// マウスが乗るInspectorウィンドウの取得
EditorWindow srcWindow = null;
int srcIndex = -1;
for (int i = 0; i < inspectors.Length; i++)
{
if (EditorWindow.mouseOverWindow.GetHashCode() == inspectors[i].GetHashCode())
{
srcIndex = i;
srcWindow = inspectors[i];
break;
}
}
if (srcWindow == null) { return; } // not found
if (GetInspectedObject(srcWindow) == null) { return; } // オブジェクトを表示していない
var scrollPositions = inspectors.Select(window => s_TypeInspectorWindow.GetField("m_ScrollPosition", k_GetFlags)).ToArray(); // InspectorWindow.cs の m_ScrollPosition取得
Vector2 srcPosition = (Vector2)scrollPositions[srcIndex].GetValue(srcWindow);
// スクロール値の設定
for (int i = 0; i < inspectors.Length; i++)
{
if (i == srcIndex) { continue; }
scrollPositions[i].SetValue(inspectors[i], srcPosition);
inspectors[i].Repaint();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment