Unity面板监听处理
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;
internal class SelectionHelper
{
[InitializeOnLoadMethod]
private static void Start()
{
//在Hierarchy面板按空格键相当于开关GameObject
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
//在Project面板按空格键相当于Show In Explorer
EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI;
}
private static void ProjectWindowItemOnGUI(string guid, Rect selectionRect)
{
if (Event.current.type == EventType.KeyDown
&& Event.current.keyCode == KeyCode.Space
&& selectionRect.Contains(Event.current.mousePosition))
{
string strPath = AssetDatabase.GUIDToAssetPath(guid);
if (Path.GetExtension(strPath) == string.Empty) //文件夹
{
Process.Start(Path.GetFullPath(strPath));
}
else //文件
{
Process.Start("explorer.exe", "/select," + Path.GetFullPath(strPath));
}
Event.current.Use();
}
}
private static void HierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
{
Event e = Event.current;
if (e.type == EventType.KeyDown)
{
switch (e.keyCode)
{
case KeyCode.Space:
ToggleGameObjcetActiveSelf();
e.Use();
break;
}
}
else if(e.type == EventType.MouseDown && e.button == 2)
{
SetAllActive();
e.Use();
}
}
internal static void ToggleGameObjcetActiveSelf()
{
Undo.RecordObjects(Selection.gameObjects, "Active");
foreach (var go in Selection.gameObjects)
{
go.SetActive(!go.activeSelf);
}
}
//按鼠标中键,将Root节点下的所有子物体显示出来
static void SetAllActive()
{
var children = Selection.activeGameObject.GetComponentsInChildren<Transform>(true);
foreach (var child in children)
{
var gameObj = child.gameObject;
Undo.RecordObject(gameObj, "SetActive");
gameObj.SetActive(true);
}
}
}
知识点:
string s1 = Path.GetExtension("D:\\dir\\asp.net\\readme.txt"); // .txt
string s2 = Path.GetExtension("D:\\dir\\asp.net\\readme."); // 零长度字符串
string s3 = Path.GetExtension("D:\\dir\\asp.net\\readme"); // 零长度字符串
string s4 = Path.GetExtension("D:\\dir\\asp.net\\readme\\"); // 零长度字符串
string s5 = Path.GetExtension("D:\\"); // 零长度字符串
string s6 = Path.GetExtension("D:"); // 零长度字符串
string s1 = Path.GetFileName("D:\\dir\\asp.net\\readme.txt"); // readme.text
string s2 = Path.GetFileName("D:\\dir\\asp.net\\readme."); // readme.
string s3 = Path.GetFileName("D:\\dir\\asp.net\\readme"); // readme
string s4 = Path.GetFileName("D:\\dir\\asp.net\\readme\\"); // 零长度字符串
string s5 = Path.GetFileName("D:\\"); // 零长度字符串
string s6 = Path.GetFileName("D:"); // 零长度字符串
只要不是以 \ 或 / 结束,都是当作文件对待(盘符除外)
string s1 = Path.GetDirectoryName("D:\\dir\\asp.net/readme.txt"); // D:\dir\asp.net
string s2 = Path.GetDirectoryName("D:\\dir\\asp.net/readme."); // D:\dir\asp.net
string s3 = Path.GetDirectoryName("D:\\dir\\asp.net/readme"); // D:\dir\asp.net
string s4 = Path.GetDirectoryName("D:\\dir\\asp.net/readme/"); // D:\dir\asp.net\readme
string s5 = Path.GetDirectoryName("D:\\"); // null,注意是 null
string s6 = Path.GetDirectoryName("D:"); // null,注意是 null
System.Diagnostics.Process.Start(); 能做什么呢?它主要有以下几个功能:
1、打开某个链接网址(弹窗)。
2、定位打开某个文件目录。
3、打开系统特殊文件夹,如“控制面板”等。
(1) publicbool Start ()
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "iexplore.exe"; //IE浏览器,可以更换
process.StartInfo.Arguments = "http://www.baidu.com";
process.Start();
(2) publicstaticProcessStart (ProcessStartInfostartInfo)
System.Diagnostics.ProcessStartInfo processStartInfo = new
System.Diagnostics.ProcessStartInfo();
processStartInfo.FileName = "explorer.exe"; //资源管理器
processStartInfo.Arguments = @"D:\";
System.Diagnostics.Process.Start(processStartInfo);
(3) publicstaticProcessStart (stringfileName)
System.Diagnostics.Process.Start(@"D:\Program Files\Tencent\QQ\Bin\QQ.exe"); //直接
调用打开文件
(4) Process.Start (StringfileName, Stringarguments)
System.Diagnostics.Process.Start("explorer.exe", "D:\\Readme.txt"); //直接打开文件
Readme.txt
上面已经举例了用process.start()打开网站的方法,现在讲讲用processs.star()定位到某个文件的
方法。
这种定位方法类似于快捷方式上的查找目标://explorer /select,"D:\Program Files\Tencent
\QQ\Bin\QQ.exe"
String path = @"D:\Program Files\Tencent\QQ\Bin\QQ.exe";
System.Diagnostics.Process.Start("explorer.exe", "/select," +path); //定位打开D:\Program
Files\Tencent\QQ\Bin文件目录并选中了QQ.exe
注意:/select后还有个逗号(,)。
[InitializeOnLoad]
[InitializeOnLoadMethod]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
[RuntimeInitializeOnLoadMethod]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
BeforeRuntime、Awake、OnRuntime、AfterRuntime、Start、Update
using UnityEngine;
using UnityEditor;
[InitializeOnLoad]
public class LoadOrderTest
{
static LoadOrderTest()
{
MyOnStart();
EditorApplication.update = MyUpdate;
}
static void MyOnStart()
{
Debug.Log("MyOnStart");
}
static void MyUpdate()
{
//if(Application.isFocused)
//{
// Debug.Log("鼠标点击进入了Game窗口");
//}
//else
//{
// Debug.Log("鼠标移除Game窗口,并点击了别的地方");
//}
if (Application.isPlaying)
{
Debug.Log("点击了 play 按钮 进入运行时");
}
else
{
Debug.Log("点击 play 按钮 进入 editor模式");
}
}
[InitializeOnLoadMethod]
static void InitializeOnLoadMethod()
{
Debug.Log("InitializeOnLoadMethod");
}
}
这个脚本放在,Editor文件夹下,添加了InitializeOnLoad特性后,其构造方法会自动执行,测试结果是,每次修改这个类的内容,就会重新执行一变构造方法。可以在构造方法中执行一些操作,来控制Editor模式下的代码执行。
我这里是,定义了一个OnStart,和EditorApplication.update赋值,效果类似Mono的Start、Update方法。
InitializeOnLoadMethod特性定义的方法,也会在构造方法之后执行一遍。