功能的实现历程
在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().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().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
///
/// Remove the default directory path from a path
///
///
///
private string ReplacePath(string FullPath)
{
//A directory
string DPath = GetPath(fileLocation).Replace(@"\", "/");
string p = FullPath.Replace(DPath, "");
return p;
}
///
/// Check 默认路径是否准确
///
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;
}
///
/// Returns the corresponding segment A directory path based on the enumeration
///
///
///
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;
}
///
/// Get Full Path
///
///
///
///
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;
}
///
/// Get the picture according to the path
///
///
///
///
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));
}
///
/// Prompt control
///
///
///
private static void ShowNoticeBox(MessageType messageType, string message)
{
GUI.backgroundColor = Color.blue;
EditorGUILayout.HelpBox(message, messageType);
switch (messageType)
{
case MessageType.Error:
GUI.color = Color.red;
message = "Error: " + message;
break;
case MessageType.Info:
GUI.color = Color.green;
message = "Info " + message;
break;
}
//GUI.color = Color.yellow;
GUILayout.TextArea(message);
GUI.color = Color.white;
}
///
/// Checking path Correctness
///
///
private static void CheckPathIsTrue(string FullPath)
{
//Debug.Log("FullPath" + FullPath);
if (!System.IO.File.Exists(FullPath) || FullPath == string.Empty)//路径不存在
{
//Debug.Log("File not found:" + FullPath);
ShowNoticeBox(MessageType.Error, "File not found:" + FullPath);
}
else
{
//Debug.Log("File path is normal." + FullPath);
ShowNoticeBox(MessageType.Info, "File path is normal." + FullPath);
}
}
}
#endif
}
完美~
发布会报错 The type or namespace name ‘Editor’ could not be found
参考文章:https://blog.csdn.net/qq_42139931/article/details/123206376 参考文章:https://wenku.baidu.com/view/1b41bac9561810a6f524ccbff121dd36a32dc422.html 官方文档:https://docs.unity3d.com/2018.4/Documentation/ScriptReference/EditorUtility.OpenFilePanel.html