Unity 从Inspector界面打开资源管理器选择并记录文件路径

Posted unity工具人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 从Inspector界面打开资源管理器选择并记录文件路径相关的知识,希望对你有一定的参考价值。

一个小功能的实现历程


在AvProVideo插件中有个功能,点击视频组件中的按钮可以打开资源管理器窗口,找到目标视频资源并记录下资源路径。
想要实现并不难,主要有两点
一个是unity 自带的用于打开资源管理器的方法

EditorUtility.OpenFilePanel();

第二个就是自定义编辑器的操作

实现过程

阶段一(初步实现):

脚本1:定义窗口、打开资源管理器

using UnityEngine;
using UnityEditor;

public class Example : EditorWindow

    static GameObject _objectBuilderScript;
    //[MenuItem("SKFramework/Example")]
    public static void Open(GameObject objectBuilderScript)
    
        GetWindow<Example>().Show();
        _objectBuilderScript = objectBuilderScript;
    

    
    private string path;

    private void OnGUI()
    
        //水平布局
        GUILayout.BeginHorizontal();
        
            GUILayout.Label("路径", GUILayout.Width(50f));
            path = GUILayout.TextField(path);
            if (GUILayout.Button("浏览", GUILayout.Width(50f)))
            
            	//不用上边这个弹窗也可以
                path = EditorUtility.OpenFilePanel("成功啦 ୧☉□☉୨", Application.dataPath, "png");
                _objectBuilderScript.GetComponent<ObjectBuilderScript>().path = path;
            
        
        GUILayout.EndHorizontal();
    

脚本2:操作类

using UnityEditor;
using UnityEngine;
public class ObjectBuilderScript : MonoBehaviour

    public  string path;
    
    public void BuildObject()
    
        Example.Open(gameObject);
       

脚本3:重写Inspector界面
这个脚本要放在 Assets/Editor 文件夹下

using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(ObjectBuilderScript))]
public class ObjectBuilderEditor : Editor

    public override void OnInspectorGUI()
    
        DrawDefaultInspector();
        ObjectBuilderScript myScript = (ObjectBuilderScript)target;
        if (GUILayout.Button("选择图片资源"))
                    

            myScript.BuildObject();
        
    

可以看到我们定义了一个按钮

点击后出现弹窗

点击浏览打开资源管理器

选择文件后可以看到路径被保存下来了

阶段二(效率提升):

经过测试和实际应用,个人认为上述实现方式不够高效,因为需要多点一次弹窗内的浏览,遂做了一点点改动
脚本一:

using UnityEditor;
using UnityEngine;
using System;
public class ObjectBuilderScript : MonoBehaviour

    string  DefualtPath = Environment.CurrentDirectory+"/Resources/";
    
    public  string path;
    
    public void BuildObject()
    
        string path1 = EditorUtility.OpenFilePanel("成功啦 ୧☉□☉୨", DefualtPath, "png");
        path = ReplacePath(path1);
        print(path);
    

    public string ReplacePath(string FullPath)
    
        string DPath = Environment.CurrentDirectory.Replace(@"\\","/");
        string p = FullPath.Replace(DPath, "");       
        return p;
    

脚本二:重写面板函数

using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(ObjectBuilderScript))]
public class ObjectBuilderEditor : Editor

    public override void OnInspectorGUI()
    
        DrawDefaultInspector();
        ObjectBuilderScript myScript = (ObjectBuilderScript)target;
        if (GUILayout.Button("选择图片资源"))
        
            myScript.BuildObject();
        
    

点击Inspector中的选择按钮就可以直接打开指定目录啦

阶段三(结构优化):

功能是有了,便捷度还不够
再改!

using System;
using UnityEngine;
using UnityEditor;
///增加了初始文件夹路径的选择
public class SetFilePath : MonoBehaviour

    public FileLocation fileLocation;
    string FilePath0 = "";

    [SerializeField]
    public string path;

    public void BuildObject()
    
        FilePath0 = GetPath(fileLocation);
        string path1 = EditorUtility.OpenFilePanel("成功啦 ୧☉□☉୨", FilePath0, "png");
        path = ReplacePath(path1)==""?path: ReplacePath(path1);
        print(path);
    

    public string ReplacePath(string FullPath)
    
        //前半段
        string DPath = GetPath(fileLocation).Replace(@"\\", "/");
        print(DPath);
        string p = FullPath.Replace(DPath, "");
        return p;
    

    public string GetPath(FileLocation location)
    
        string result = string.Empty;
        switch (location)
        
            //case FileLocation.AbsolutePathOrURL:
            //    break;
            case FileLocation.RelativeToDataFolder:
                result = Application.dataPath;
                break;
            //case FileLocation.RelativeToPeristentDataFolder:
            //    result = Application.persistentDataPath;
            //    break;
            case FileLocation.RelativeToProjectFolder:
#if !UNITY_WINRT_8_1
                string path1 = "..";
#if UNITY_STANDALONE_OSX && !UNITY_EDITOR_OSX
                        path += "/..";
#endif
                result = System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, path1));
                result = result.Replace('\\\\', '/');
#endif
                break;
            case FileLocation.RelativeToStreamingAssetsFolder:
                result = Application.streamingAssetsPath;
                break;

            //default:
            //    result = path;
            //    break;
        
        return result;
    



public enum FileLocation

    //AbsolutePathOrURL,
    RelativeToProjectFolder,
    RelativeToStreamingAssetsFolder,
    RelativeToDataFolder
    //RelativeToPeristentDataFolder,
 

using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(SetFilePath),true)]
public class ObjectBuilderEditor : Editor

    public override void OnInspectorGUI()
    
        DrawDefaultInspector();

        SetFilePath myScript = (SetFilePath)target;
        if (GUILayout.Button("选择图片资源"))
        
            myScript.BuildObject();
        
    

这样需要用到这个功能的对象直接继承SetFilePath就好啦

阶段四(功能补充):

功能测了测没问题,再加个贴心的小提示吧

using System;
using UnityEngine;
using UnityEditor;
namespace LAIALAIA

    public class SetFilePath : MonoBehaviour
    
        public FileLocation fileLocation;
        string FilePath0 = "";
        public string path;
#if UNITY_EDITOR
        public void BuildObject()
        
            FilePath0 = GetPath(fileLocation);
            //待更新
            string path1 = EditorUtility.OpenFilePanel("成功啦 ୧☉□☉୨", FilePath0, "png");
            

            string path2 = "";

            if (string.IsNullOrEmpty(path1))
            
                print("未选择");
                //return;
            
            else
            
                fileLocation = CheckFileLocationPath(path1);
                if (fileLocation != FileLocation.AbsolutePathOrURL)
                    path2 = ReplacePath(path1) == "" ? path : ReplacePath(path1); //只留后半段
                else
                    path2 = path1;
                path = path2;
            
        
#endif
        /// <summary>
        ///  Remove the default directory path from a path
        /// </summary>
        /// <param name="FullPath"></param>
        /// <returns></returns>
        private string ReplacePath(string FullPath)
        
            //A directory
            string DPath = GetPath(fileLocation).Replace(@"\\", "/");
            string p = FullPath.Replace(DPath, "");
            return p;
        
        /// <summary>
        /// Check 默认路径是否准确
        /// </summary>
        private FileLocation CheckFileLocationPath(string FullPath)
        
            FileLocation fLocation = FileLocation.AbsolutePathOrURL;
            foreach (FileLocation f in Enum.GetValues(typeof(FileLocation)))
            
                fLocation = f;
                if (f != FileLocation.AbsolutePathOrURL)
                
                    string gp = GetPath(f);
                    //是否包含 目标 路径
                    if (FullPath.Contains(gp)) break;
                    else fLocation = FileLocation.AbsolutePathOrURL;
                    //print(gp);
                
            
            //print("fileLocation:" + fileLocation);
            return fLocation;
        

        /// <summary>
        /// Returns the corresponding segment A directory path based on the enumeration
        /// </summary>
        /// <param name="location"></param>
        /// <returns></returns>
        private static string GetPath(FileLocation location)
        
            string result = string.Empty;
            switch (location)
            
                case FileLocation.AbsolutePathOrURL:
                    break;
                case FileLocation.RelativeToDataFolder:
                    result = Application.dataPath;
                    break;
                //case FileLocation.RelativeToPeristentDataFolder:
                //    result = Application.persistentDataPath;
                //    break;
                case FileLocation.RelativeToProjectFolder:
#if !UNITY_WINRT_8_1
                    string path1 = "..";
#if UNITY_STANDALONE_OSX && !UNITY_EDITOR_OSX
                        path += "/..";
#endif
                    result = System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, path1));
                    result = result.Replace('\\\\', '/');
#endif
                    break;
                case FileLocation.RelativeToStreamingAssetsFolder:
                    result = Application.streamingAssetsPath;
                    break;

                    //default:
                    //    result = path;
                    //    break;
            
            //print(result);
            return result;
        

        /// <summary>
        /// Get Full Path
        /// </summary>
        /// <param name="path"></param>
        /// <param name="location"></param>
        /// <returns></returns>
        public string GetFilePath(string path, FileLocation location)
        
            string result = string.Empty;
            if (!string.IsNullOrEmpty(path))
            
                switch (location)
                
                    case FileLocation.AbsolutePathOrURL:
                        result = path;
                        break;
                    case FileLocation.RelativeToDataFolder:
                    case FileLocation.RelativeToProjectFolder:
                    case FileLocation.RelativeToStreamingAssetsFolder:
                        result = GetPath(location) + path;
                        //result = System.IO.Path.Combine(GetPath(location), path);
                        //print(result);
                        break;
                
            
            //print(result);
            return result;
        
        /// <summary>
        /// Get the picture according to the path
        /// </summary>
        /// <param name="path"></param>
        /// <param name="location"></param>
        /// <returns></returns>
        public Sprite GetSprite()
        
            string result = string.Empty;
            if (!string.IsNullOrEmpty(path))
            
                switch (fileLocation)
                
                    case FileLocation.AbsolutePathOrURL:
                        result = path;
                        break;
                    case FileLocation.RelativeToDataFolder:
                    case FileLocation.RelativeToProjectFolder:
                    case FileLocation.RelativeToStreamingAssetsFolder:
                        result = GetPath(fileLocation) + path;
                        //result = System.IO.Path.Combine(GetPath(location), path);
                        //print(result);
                        break;
                
            
            Sprite sprite = TextureLoad.LoadOneImage(result);
            //print(result);
            return sprite;
        

        private string GetStartFolder(string path, FileLocation fileLocation)
        
            // Try to resolve based on file path + file location
            string result = GetFilePath(path, fileLocation);
            if (!string.IsNullOrEmpty(result))
            
                if (System.IO.File.Exists(result))
                    result = System.IO.Path.GetDirectoryName(result);
            

            if (!System.IO.Directory.Exists(result))
            
                // Just resolve on file location
                result = GetPath(fileLocation);
            
            if (string.IsNullOrEmpty(result))
            
                // Fallback
                result = Application.streamingAssetsPath;//用默认的streamingAssetsPath
            
            return result;
        
    


    public enum FileLocation
    
        AbsolutePathOrURL,
        RelativeToStreamingAssetsFolder,
        RelativeToDataFolder,
        RelativeToProjectFolder
        //RelativeToPeristentDataFolder,
    

#if UNITY_EDITOR
    //using UnityEngine;
    //using UnityEditor;
    //using System;
    [CustomEditor(typeof(SetFilePath), true)]
    public class ObjectBuilderEditor : Editor
    
        public override void OnInspectorGUI()
        
            DrawDefaultInspector();
            SetFilePath myScript = (SetFilePath)target;
            if (GUILayout.Button("选择图片资源"))
                myScript.BuildObject();

            CheckPathIsTrue(myScript.GetFilePath(myScript.path, myScript.fileLocation));
        
        /// <summary>
        /// Prompt control
        /// </summary>
        /// <param name="

Unity Animation需要Inspector打开Debug模式,然后勾选Legacy

 

以上是关于Unity 从Inspector界面打开资源管理器选择并记录文件路径的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D材质 Material ( 材质简介 | 创建材质 | 设置材质属性 | 对 3D 物体应用材质 | 资源拖动到 Inspector 检查器中的 Material 属性中 )

Unity2.7 检视器(Inspector)

Unity 自定义inspector界面如何显示数组

Unity Animation需要Inspector打开Debug模式,然后勾选Legacy

扩展Unity Inspector

unity中的inspector关闭之后,怎么再找出来?在线急