Unity的资源选择面板自带的筛选不方便指定筛选

我想要既可以使用Unity自带的筛选面板,又需要指定他去筛选我指定的文件夹下的物体,或者说我指定的物体,直接使用搜索 只能搜索一个类型,或者名称相似的,我又不想自己写面板,用原生的比较简介,所以我看了内部Api 用反射打开自带的筛选面板,并且可以自己在外面筛选好了,直接显示筛选结果,话不多说直接上代码,看得懂就看,看不懂就算,用的版本是Unity 2020.3 其他版本的内部Api可能会有改动,如果用不了 会替换的自行替换内部方法名称

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEditor.SearchService;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Editor
{
    public class TestMenu
    {
        //private static CusTomObjectSelector selector = new CusTomObjectSelector();
        [MenuItem("Test/测试代码")]
        public static void OpenSearchPanelConsole()
        {
            SerializedProperty property =
                new SerializedObject(ScriptableObject.CreateInstance<TestProperty>()).FindProperty("texture2D");
            ObjectSelectHelper.OpenUnityObjSearchPanel(typeof(Texture2D), property, false, null, OnSelect, OnSelectUpdate);
            
        }
        
        [MenuItem("Test/测试指定获取 ")]
        public static void OpenSearchPanelConsoleWithId()
        {
            string path = "Assets/Editor/Images";
            var files = Directory.GetFiles(path);
            List<int> guids = new List<int>();
            var newFiles = new List<string>();
            Dictionary<string,int> mapInstanceId = new Dictionary<string, int>();
            foreach (var file in files)
            {
                if (!file.EndsWith(".meta"))
                {
                    var newfile = file.Replace("\\", "/");
                    newfile = newfile.Replace(Application.dataPath, "Assets");
                    newFiles.Add(newfile);
                    var guid = AssetDatabase.LoadAssetAtPath<Texture2D>(newfile);
                    guids.Add(guid.GetInstanceID());
                    mapInstanceId.Add(newfile,guid.GetInstanceID());
                }
                
            }
            int[] OnCustomSearch(string arg)
            {
                List<int> aaa = new List<int>();
                foreach (var newFile in newFiles)
                {
                    if (newFile.Contains(arg))
                    {
                        if (mapInstanceId.TryGetValue(newFile, out var instanceId))
                        {
                            aaa.Add(instanceId);
                        }
                        
                    }
                }

                return aaa.ToArray();
            }
            SerializedProperty property =
                new SerializedObject(ScriptableObject.CreateInstance<TestProperty>()).FindProperty("texture2D");
            ObjectSelectHelper.OpenUnityObjSearchPanel(typeof(Texture2D), property, false, guids, OnSelect, OnSelectUpdate,OnCustomSearch);
            
        }

        

        public static void OnSelect(Object select)
        {
            //UnityEditor.SearchService.ObjectSelector.UnregisterEngine(selector);
            if (select != null)
            {
                Debug.Log("选择" + select.name);
            }
        }

        public static void OnSelectUpdate(Object select)
        {
            if (select != null)
            {
                Debug.Log("刷新" + select.name);
            }
        }

        public static void AddMethod(int a, int b)
        {
            // add a method
        }
        
    }
}


public class ObjectSelectHelper
{
    /// <summary>
    /// 封装的直接打开Unity选择物体面板
    /// </summary>
    /// <param name="searchType">筛选类型</param>
    /// <param name="serializedProperty">需要修改的属性</param>
    /// <param name="isShowScene">是否展示场景内</param>
    /// <param name="customSearchInstanceIds">自我筛选后得到的物体实例Id</param>
    /// <param name="selectAction">确认选择返回</param>
    /// <param name="selectUpdateAction">持续选择返回</param>
    public static void OpenUnityObjSearchPanel(Type searchType, SerializedProperty serializedProperty, bool isShowScene,
        List<int> customSearchInstanceIds = null, Action<Object> selectAction = null, Action<Object> selectUpdateAction = null,Func<string,int[]> customSearch = null)
    {
        var editorAssembly = typeof(UnityEditor.Editor).Assembly;
        Type objectSelectorType = editorAssembly.GetType("UnityEditor.ObjectSelector");
        PropertyInfo getProperty = objectSelectorType.GetProperty("get", BindingFlags.Static | BindingFlags.Public);
        MethodInfo showMethod = objectSelectorType.GetMethod("Show", BindingFlags.NonPublic | BindingFlags.Instance,
            null,
            new[]
            {
                typeof(Type), typeof(SerializedProperty), typeof(bool), typeof(List<int>), typeof(Action<Object>),
                typeof(Action<Object>)
            }, null);
        var DelayerType = editorAssembly.GetType("UnityEditor.Delayer");
        var createMethod = DelayerType.GetMethod("Debounce", BindingFlags.Static | BindingFlags.Public);
        var m_DebounceField = objectSelectorType.GetField("m_Debounce", BindingFlags.Instance | BindingFlags.NonPublic);
        var m_ListAreaInfo = objectSelectorType.GetField("m_ListArea", BindingFlags.Instance | BindingFlags.NonPublic);
        
        object[] arguments = new object[]
        {
            searchType,
            serializedProperty,
            false,
            null,
            selectAction,
            selectUpdateAction
        };
        var objectSelector = getProperty.GetValue(null);

        //打开面板
        showMethod.Invoke(objectSelector, arguments);

        //如果有自定义显示结果,直接展示自定义结果
        if (customSearchInstanceIds != null && customSearchInstanceIds.Count > 0)
        {
            //刷新成给定列表
            var m_ListArea = m_ListAreaInfo.GetValue(objectSelector);
            var showObjectsInListMethod = m_ListArea.GetType()
                .GetMethod("ShowObjectsInList", BindingFlags.Instance | BindingFlags.Public);
            //替换刷新方法
            Action<object> action = (obj) =>
            {
                var searchFilter = objectSelectorType.GetField("m_SearchFilter", BindingFlags.Instance | BindingFlags.NonPublic);
                if (customSearch != null)
                {
                    var newInstanceIds = customSearch.Invoke(searchFilter.GetValue(objectSelector).ToString());
                    if (showObjectsInListMethod != null)
                    {
                        showObjectsInListMethod.Invoke(m_ListArea, new object[] {newInstanceIds});
                    }
                }
            };
            m_DebounceField.SetValue(objectSelector, createMethod.Invoke(null, new object[] {action, 0.2f}));

            if (showObjectsInListMethod != null)
            {
                showObjectsInListMethod.Invoke(m_ListArea, new object[] {customSearchInstanceIds.ToArray()});
            }
        }
       
        
        Debug.Log("尝试获取");
    }
}


public class TestProperty : ScriptableObject
{
    public Texture2D texture2D;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值