在开始今天的编辑器扩展之前,先说一下unity的一大基类的,可能所有的unity程序员都熟悉MonoBehaviour 和Editor。但是unity其实还为我们准备了两个很厉害的类,它们分别是ScriptableObject和EditorWindow。
ScriptableObject
首先聊聊ScriptableObject类,它可以用于生成一个.asset文件,我称之为一个数据容器,用来储存序列化和反序列化的数据。一些简单的数据也可以不用xml或者josn储存啦。
111.png 222.png
上面的图片可以看到,我们生成了一个.asset文件,点击它可以在inspector面板上面显示相关数据。
EditorWindow
现在我们来聊聊EditorWindow,就像图片显示的情况一样,虽然我们可以点击.asset文件然后在inspector面板上面修改和查看数据,但是有一个问题就是当项目越来越大的时候每次要修改数据都要在Project里面慢慢去找文件非常麻烦。所以我们可以考虑扩展编辑器窗口。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
namespace MyUtility
{
/// <summary>
/// 显示 查找的 第一个 ScriptableObject
/// </summary>
public abstract class ScriptableObjectBrowserEditorWindow<T> : EditorWindow where T : ScriptableObjectBrowserEditorWindow<T>
{
protected abstract string FileName { get; }
Object settings = null;
Editor editor = null;
Vector2 scrollPos;
public static void OpenWindow(string windowName)
{
T window = GetWindow<T>(windowName);
window.position = new Rect(Screen.width / 2, Screen.height / 2, 500, 500);
window.Show();
}
Object[] getProjectObjs(string filter)
{
string[] guids = UnityEditor.AssetDatabase.FindAssets(filter);
string[] paths = new string[guids.Length];
Object[] returnObjs = new Object[guids.Length];
for (int i = 0; i < guids.Length; i++)
{
paths[i] = AssetDatabase.GUIDToAssetPath(guids[i]);
returnObjs[i] = AssetDatabase.LoadAssetAtPath<Object>(paths[i]);
}
return returnObjs;
}
protected void findAsset()
{
Object[] objs = getProjectObjs("t:" + FileName); // 一定要记住这里要加上"t:",不要直接用文件名称,
if (objs.Length > 0) // 不然得到的是继承ScriptableObject的脚本,而不是.asset文件
{
settings = objs[0];
editor = Editor.CreateEditor(settings);
}
}
protected virtual void OnEnable()
{
findAsset();
}
void OnGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
if (GUILayout.Button("ReFresh", GUILayout.Width(100)))
{
findAsset();
}
EditorGUILayout.Space();
EditorGUILayout.Space();
if (settings != null && editor != null)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField(settings, typeof(Object), false);
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
editor.OnInspectorGUI();
}
EditorGUILayout.EndScrollView();
}
void OnInspectorUpdate()
{
this.Repaint();
}
}
}
上面这个脚本便是继承于EditorWindow。但是有几个地方想说明一下
AssetDatabase.FindAssets
AssetDatabase.GUIDToAssetPath
AssetDatabase.LoadAssetAtPath
上面三个方法一般是搭配出现,首先在所有资源里面查找到你所需要的文件名,可能项目里存在一个,也可能是多个。
FindAssets一般返回一个媒介,可以通过GUIDToAssetPath将媒介转换成文件所在路径。前两个方法相当于通过文件名查找到文件所在路径。LoadAssetAtPath方法则是通过路径加载文件。可能有点绕。。。
关键来了
现在我们可以扩展文件里面所有的.asset文件,只需要不到十行的代码,就可以把 inspector面板上显示的信息扩展一个新的窗口显示出来了。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MyUtility;
public class AudioSettingsEditorWindow : ScriptableObjectBrowserEditorWindow<AudioSettingsEditorWindow>
{
protected override string FileName
{
get { return "PacManAudioSetting"; }
}
[MenuItem("Tools/PacManAudioSetting")]
static void Open()
{
OpenWindow("AudioSetting");
}
这就是效果图,和在项目里慢慢去找到.asset文件,点击显示在面板上面的内容一模一样了
999.png
好了,本次水文结束
网友评论