文章目录
- 前言
- 创建一个Editor窗口
- Unity引擎目前中焦的窗口
- Editor窗口鼠标悬停
- Editor窗口场景编辑更改监听
- 主窗口停靠下最大化窗口
- 设置窗口的小图标
- 获取中焦窗口
- Window.ShowNotification
- Window.SendEvent
- EditorWindow.OnHierarchyChange()
- EditorWindow.OnProjectChange()
前言
学习下编辑器的写法,主要可以用来做一些流程化的东西,帮助自己提高下工作效率
创建一个Editor窗口
在Unity中都是基于窗口进行工作的。Game窗口用查看游戏运行的实际情况,Scene窗口用来看游戏场景等等,窗口就是Unity引擎工作流的核心灵魂。
写创建一个cs文件,命名ExcelWindow.cs,编写代码如下
using UnityEditor;
public class ExcelWindow : EditorWindow
{
[MenuItem("Excel/ExcelWindow")]
private static void ShowExcelProcessWindow()
{
var window = GetWindow<ExcelWindow>();
window.Show();
}
}
MenuItem特性能直接在Unity的菜单栏中加上一个路径Excel/ExcelWindow,再加上通过GetWindow方法得到对应Window的实例,调用Show方法来进行窗口的显示。
Unity引擎目前中焦的窗口
通过EditorWindow自己的静态字段focusedWindow来获取中焦窗口,在EditorWindow类添加如下代码
private void OnGUI()
{
EditorGUILayout.LabelField(EditorWindow.focusedWindow.ToString());
}
这样就能在Excel面板上获取当前中焦的参考,OnGUI是Unity自带的GUI刷新函数,会一直进行刷新。
Editor窗口鼠标悬停
mouseOverWindow与fouseWindow相似,这个是鼠标悬停在哪个Window,这个静态变量就是那个窗口。
void OnInspectorUpdate()
{
if (EditorWindow.mouseOverWindow)
EditorWindow.mouseOverWindow.Focus();//就是当鼠标移到那个窗口,这个窗口就自动聚焦
this.Repaint();//重画MyWindow窗口,更新Label
}
功能很简单,鼠标移动的哪个窗口,在MyWindow打印那个窗口的信息,并且自动聚焦到那个窗口。
反正我是成功了,你们可以自行测试。
Editor窗口场景编辑更改监听
很多时候,我们都是在Scene面板上进行编辑工作,一些编辑器功能要做一些实时刷新的工作,只有在编辑Scene才刷新窗口,一般情况下不进行任何刷新。可以设置对应的window类的autoRepaintOnSceneChange = true。
[MenuItem("Excel/ExcelWindow")]
private static void ShowExcelProcessWindow()
{
var window = GetWindow<ExcelWindow>();
window.autoRepaintOnSceneChange = false;
window.Show(true);
}
主窗口停靠下最大化窗口
maximized只有在窗口停靠在主窗口的情况下才能使用的选项,这里添加设置一个窗口向左的Toggle来进行测试,代码如下。
private void OnGUI()
{
maximized = EditorGUILayout.ToggleLeft("Max", maximized);
}
当窗口停靠在主窗口上才能失效,点击max的toggle就能进行这个窗口的最大化。
设置窗口的小图标
通过GUIContent.GUIContent来修改窗口的icon小图标
获取中焦窗口
EditorGUILayout.LabelField("聚焦窗口名字"+EditorWindow.focusedWindow.ToString());
Window.ShowNotification
使用这个方法打印的消息不会像消息盒子一样自动消失,必须手动调用RemoveNotiftcation才会这个文本消失,编码如下:
m_notification = EditorGUILayout.TextField(m_notification);
if (GUILayout.Button("Show Notification"))
{
myWindow.ShowNotification(new GUIContent(m_notification));
}
if (GUILayout.Button("Remove Notification"))
{
myWindow.RemoveNotification();
}
Window.SendEvent
这个方法就是传递事件的方法,什么意思,也就是说比如你想在Hierarchy窗口粘贴要复制的Cube,那么这个粘贴他是一个事件,那么正常我们是用鼠标操作粘贴,如果我们想要用代码控制,就得使用该方法,直接传递粘贴事件给Hierarchy窗口就行了。
EditorGUIUtility.CommandEvent("Paste");
这个方法是通过事件名字取得事件,OK,我们来写下代码:
using UnityEngine;
using System.Collections;
using UnityEditor;
public class MyWindow: EditorWindow
{
static MyWindow myWindow;
[MenuItem("Window/MyWindow")]//在unity菜单Window下有MyWindow选项
static void Init()
{
myWindow = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow), false, "MyWindow", false);
myWindow.Show();
}
void OnEnable()
{
}
void OnGUI()
{
if (EditorWindow.focusedWindow.ToString().Trim() == "(UnityEditor.SceneHierarchyWindow)")
{
EditorWindow.focusedWindow.SendEvent(EditorGUIUtility.CommandEvent("Paste"));//传递粘贴的事件
}
}
}
EditorWindow.OnHierarchyChange()
这个方法是当Hierarchy视窗改变的时候,会执行这个方法的逻辑。
当Transform组件参数改变的时候,这里注意下你在视窗Scene中拖动坐标轴是不会监听到,只有在Inspector视窗中手动改Transform的值才发生监听。
还有GameObject的名称改变会有触发事件监听,还有创建,删除,粘贴等等操作,都会被监听到。
写个小例子测试下:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class MyWindow : EditorWindow
{
static EditorWindow myWindow;
[MenuItem("Window/MyWindow")]
static void Init()
{
myWindow = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow), false, "MyWindow", false);
myWindow.Show();
}
void OnHierarchyChange()
{
Debug.Log("Sync");
}
}
EditorWindow.OnProjectChange()
这个方法和上述类似,是Project视窗发生改变的时候,会执行该方法。
比如说导入文件,移动文件,等等,当然包括删除文件。
这里我就不演示了,和上述类似。
EditorWindow.OnSelectionChange()
这个方法是当你选择的物件发生变化(包括Scene,Project和Hierarchy视窗)的时候会执行该方法。