Unity3D之监听Hierachy、Project等视图结构变化的事件
2015-01-27 20:47
399 查看
以前就有人问我怎么监听Hierarchy视图中创建或删除变化的事件,当时因为有别的事情就没研究这块。刚好最近有这一类的需求我就学习学习。网上发现了一个日本人写的文档,实现的原理很有意思,内容不错我就翻译一下。
请注意一定把这两个监听的脚本放在Editor文件夹下。
先是基类。
using System;
using System.Collections;
using System.Reflection;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class EditorMonoBehaviour
{
static EditorMonoBehaviour ()
{
var type = Types.GetType ("UnityEditor.EditorAssemblies", "UnityEditor.dll");
var method = type.GetMethod ("SubclassesOf", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[]{ typeof(Type) }, null);
var e = method.Invoke (null, new object[]{ typeof(EditorMonoBehaviour) }) as IEnumerable;
foreach (Type editorMonoBehaviourClass in e) {
method = editorMonoBehaviourClass.BaseType.GetMethod ("OnEditorMonoBehaviour", BindingFlags.NonPublic | BindingFlags.Instance);
if (method != null) {
method.Invoke (System.Activator.CreateInstance (editorMonoBehaviourClass), new object[0]);
}
}
}
private void OnEditorMonoBehaviour ()
{
EditorApplication.update += Update;
EditorApplication.hierarchyWindowChanged += OnHierarchyWindowChanged;
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
EditorApplication.projectWindowChanged += OnProjectWindowChanged;
EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI;
EditorApplication.modifierKeysChanged += OnModifierKeysChanged;
// globalEventHandler
EditorApplication.CallbackFunction function = () => OnGlobalEventHandler (Event.current);
FieldInfo info = typeof(EditorApplication).GetField ("globalEventHandler", BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
EditorApplication.CallbackFunction functions = (EditorApplication.CallbackFunction)info.GetValue (null);
functions += function;
info.SetValue (null, (object)functions);
EditorApplication.searchChanged += OnSearchChanged;
EditorApplication.playmodeStateChanged += () => {
if (EditorApplication.isPaused) {
OnPlaymodeStateChanged (PlayModeState.Paused);
}
if (EditorApplication.isPlaying) {
OnPlaymodeStateChanged (PlayModeState.Playing);
}
if (EditorApplication.isPlayingOrWillChangePlaymode) {
OnPlaymodeStateChanged (PlayModeState.PlayingOrWillChangePlaymode);
}
};
}
public virtual void Update ()
{
}
public virtual void OnHierarchyWindowChanged ()
{
}
public virtual void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
{
}
public virtual void OnProjectWindowChanged ()
{
}
public virtual void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
{
}
public virtual void OnModifierKeysChanged ()
{
}
public virtual void OnGlobalEventHandler (Event e)
{
}
public virtual void OnSearchChanged ()
{
}
public virtual void OnPlaymodeStateChanged (PlayModeState playModeState)
{
}
public enum PlayModeState
{
Playing,
Paused,
Stop,
PlayingOrWillChangePlaymode
}
}
复制代码
接着是继承类,所有监听的事件在这里完成,两个类都不用实例化也不用NEW直接就可以监听。
using UnityEditor;
using UnityEngine;
public class NewBehaviourScript : EditorMonoBehaviour
{
public override void Update ()
{
//Debug.Log ("每一帧回调一次");
}
public override void OnPlaymodeStateChanged (PlayModeState playModeState)
{
//Debug.Log ("游戏运行模式发生改变, 点击 运行游戏 或者暂停游戏或者 帧运行游戏 按钮时触发: " + playModeState);
}
public override void OnGlobalEventHandler (Event e)
{
//Debug.Log ("全局事件回调: " + e);
}
public override void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
{
// Debug.Log (string.Format ("{0} : {1} - {2}", EditorUtility.InstanceIDToObject (instanceID), instanceID, selectionRect));
}
public override void OnHierarchyWindowChanged ()
{
Debug.Log ("层次视图发生变化");
}
public override void OnModifierKeysChanged ()
{
// Debug.Log ("当触发键盘事件");
}
public override void OnProjectWindowChanged ()
{
// Debug.Log ("当资源视图发生变化");
}
public override void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
{
//根据GUID得到资源的准确路径
//Debug.Log (string.Format ("{0} : {1} - {2}", AssetDatabase.GUIDToAssetPath (guid), guid, selectionRect));
}
}
复制代码
思考:因为在这里我们只能得到它变化的事件,但是我们不知道哪个GameObject变化了。所以我觉得可以自己写一段代码来对比一下前后。
请注意一定把这两个监听的脚本放在Editor文件夹下。
先是基类。
using System;
using System.Collections;
using System.Reflection;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class EditorMonoBehaviour
{
static EditorMonoBehaviour ()
{
var type = Types.GetType ("UnityEditor.EditorAssemblies", "UnityEditor.dll");
var method = type.GetMethod ("SubclassesOf", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[]{ typeof(Type) }, null);
var e = method.Invoke (null, new object[]{ typeof(EditorMonoBehaviour) }) as IEnumerable;
foreach (Type editorMonoBehaviourClass in e) {
method = editorMonoBehaviourClass.BaseType.GetMethod ("OnEditorMonoBehaviour", BindingFlags.NonPublic | BindingFlags.Instance);
if (method != null) {
method.Invoke (System.Activator.CreateInstance (editorMonoBehaviourClass), new object[0]);
}
}
}
private void OnEditorMonoBehaviour ()
{
EditorApplication.update += Update;
EditorApplication.hierarchyWindowChanged += OnHierarchyWindowChanged;
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
EditorApplication.projectWindowChanged += OnProjectWindowChanged;
EditorApplication.projectWindowItemOnGUI += ProjectWindowItemOnGUI;
EditorApplication.modifierKeysChanged += OnModifierKeysChanged;
// globalEventHandler
EditorApplication.CallbackFunction function = () => OnGlobalEventHandler (Event.current);
FieldInfo info = typeof(EditorApplication).GetField ("globalEventHandler", BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
EditorApplication.CallbackFunction functions = (EditorApplication.CallbackFunction)info.GetValue (null);
functions += function;
info.SetValue (null, (object)functions);
EditorApplication.searchChanged += OnSearchChanged;
EditorApplication.playmodeStateChanged += () => {
if (EditorApplication.isPaused) {
OnPlaymodeStateChanged (PlayModeState.Paused);
}
if (EditorApplication.isPlaying) {
OnPlaymodeStateChanged (PlayModeState.Playing);
}
if (EditorApplication.isPlayingOrWillChangePlaymode) {
OnPlaymodeStateChanged (PlayModeState.PlayingOrWillChangePlaymode);
}
};
}
public virtual void Update ()
{
}
public virtual void OnHierarchyWindowChanged ()
{
}
public virtual void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
{
}
public virtual void OnProjectWindowChanged ()
{
}
public virtual void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
{
}
public virtual void OnModifierKeysChanged ()
{
}
public virtual void OnGlobalEventHandler (Event e)
{
}
public virtual void OnSearchChanged ()
{
}
public virtual void OnPlaymodeStateChanged (PlayModeState playModeState)
{
}
public enum PlayModeState
{
Playing,
Paused,
Stop,
PlayingOrWillChangePlaymode
}
}
复制代码
接着是继承类,所有监听的事件在这里完成,两个类都不用实例化也不用NEW直接就可以监听。
using UnityEditor;
using UnityEngine;
public class NewBehaviourScript : EditorMonoBehaviour
{
public override void Update ()
{
//Debug.Log ("每一帧回调一次");
}
public override void OnPlaymodeStateChanged (PlayModeState playModeState)
{
//Debug.Log ("游戏运行模式发生改变, 点击 运行游戏 或者暂停游戏或者 帧运行游戏 按钮时触发: " + playModeState);
}
public override void OnGlobalEventHandler (Event e)
{
//Debug.Log ("全局事件回调: " + e);
}
public override void HierarchyWindowItemOnGUI (int instanceID, Rect selectionRect)
{
// Debug.Log (string.Format ("{0} : {1} - {2}", EditorUtility.InstanceIDToObject (instanceID), instanceID, selectionRect));
}
public override void OnHierarchyWindowChanged ()
{
Debug.Log ("层次视图发生变化");
}
public override void OnModifierKeysChanged ()
{
// Debug.Log ("当触发键盘事件");
}
public override void OnProjectWindowChanged ()
{
// Debug.Log ("当资源视图发生变化");
}
public override void ProjectWindowItemOnGUI (string guid, Rect selectionRect)
{
//根据GUID得到资源的准确路径
//Debug.Log (string.Format ("{0} : {1} - {2}", AssetDatabase.GUIDToAssetPath (guid), guid, selectionRect));
}
}
复制代码
思考:因为在这里我们只能得到它变化的事件,但是我们不知道哪个GameObject变化了。所以我觉得可以自己写一段代码来对比一下前后。
相关文章推荐
- 监听Hierachy、Project等视图结构变化的事件
- 监听Hierachy、Project等视图结构变化的事件
- Unity 监听Project视图结构变化的事件
- Unity3D研究院之监听Project视图结构变化的事件
- Unity监听Hierachy视图变化
- Unity3D编辑器的结构介绍之Project(工程)视图
- 所有对于Unity3D中 NGUI 触发事件的监听方法
- 【疑难问题】——Game中子弹的代码结构设计(未完)——是每个实例去监听某个事件
- Servlet事件监听器、监听servletContext域对象创建和销毁、监听三个域对象属性变化
- AndroidAnnotations——Listening to AdapterViewEvents监听适配器视图事件
- jQuery封装自定义事件--valuechange(动态的监听input,textarea)之前值,之后值的变化
- Unity3D自带案例AngryBots分析(一)——Hierarchy及Project层次结构
- rcp(插件开发)获取IWorkbenchPage对象,实现视图间的事件监听
- ios开发 监听键盘frame变化事件获取键盘高度( ios8&ios7 横竖屏旋转时需要注意的问题)
- 用JS或者jQuery监听 浏览器窗口大小的变化事件
- javascript 原生方法监听DOM结构改变事件
- unity3d NGUI 基础控件及添加监听事件
- 视图重用——监听事件
- 对 键盘 事件 监听NSNotification 处理相应页面 变化UIKeyboardAnimation
- 对 键盘 事件 监听NSNotification 处理相应页面 变化UIKeyboardAnimation