ソースコード
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEditor; using UnityEditor.PackageManager.UI; using UnityEditorInternal; using UnityEngine.UIElements; using PackageInfo = UnityEditor.PackageManager.PackageInfo; [InitializeOnLoad] internal sealed class Example : VisualElement, IPackageManagerExtension { private bool m_isInitialized; static Example() { var extension = new Example(); PackageManagerExtensions.RegisterExtension( extension ); } VisualElement IPackageManagerExtension.CreateExtensionUI() { m_isInitialized = false; return this; } void IPackageManagerExtension.OnPackageSelectionChange( PackageInfo packageInfo ) { Initialize(); } private void Initialize() { if ( m_isInitialized ) return; VisualElement root = this; while ( root != null && root.parent != null ) { root = root.parent; } var button = new Button { text = "ピカチュウ", }; var removeButton = FindElement( root, x => x.name == "PackageRemoveCustomButton" ); removeButton.parent.Add( button ); m_isInitialized = true; } void IPackageManagerExtension.OnPackageAddedOrUpdated( PackageInfo packageInfo ) { } void IPackageManagerExtension.OnPackageRemoved( PackageInfo packageInfo ) { } private static VisualElement FindElement ( VisualElement element, Func<VisualElement, bool> predicate ) { var selected = new List<VisualElement>(); var engineAssemblyPath = InternalEditorUtility.GetEngineAssemblyPath(); var engineAssemblyDirectoryName = Path.GetDirectoryName( engineAssemblyPath ).Replace( "\\", "/" ); var assembly = Assembly.LoadFile( $@"{engineAssemblyDirectoryName}/UnityEditor.UIBuilderModule.dll" ); var type = assembly.GetType( "Unity.UI.Builder.VisualElementExtensions" ); var findElementsRecursiveMethod = type.GetMethod( "FindElementsRecursive", BindingFlags.Static | BindingFlags.NonPublic ); findElementsRecursiveMethod.Invoke( null, new object[] { element, predicate, selected } ); return selected.Count == 0 ? null : selected[ 0 ]; } }
[