Last active
July 11, 2018 10:38
-
-
Save rngtm/f17884dbce7488dcd010c629c72c8c86 to your computer and use it in GitHub Desktop.
複数Inspectorのスクロールを同期するエディター拡張 (Unity2018.2.0f2で動作確認)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ///////////////////////////////////////////////////////////////////////// | |
| // 複数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