- 最后登录
- 2018-1-5
- 注册时间
- 2012-10-11
- 阅读权限
- 30
- 积分
- 651
- 纳金币
- 0
- 精华
- 3
|
上一篇我介绍了从一个NGUI视图中转移基本事件到一个对象中去处理的方法,这次我们还是用同样的方法,将Mono事件也进行转移,这样一来,我们就又可以省去很多有关挂脚本的无谓的操作了。下面是部分代码:
using UnityEngine;
using System.Collections;
#region Mono事件代理
public delegate void MonoEvent();
#endregion
public class UIMonoEventListener : MonoBehaviour
{
#region 常用Mono事件,还没有全部完成,先写常用的
/// <summary>
/// Start事件
/// </summary>
public event MonoEvent StartMono;
void Start () {
if(StartMono != null)
{ StartMono();
}
}
/// <summary>
/// Update事件
/// </summary>
public event MonoEvent UpdateMono;
void Update () {
if(UpdateMono != null)
{ UpdateMono();
}
}
/// <summary>
/// LateUpdate事件
/// </summary>
public event MonoEvent LateUpdateMono;
void LateUpdate()
{
if(LateUpdateMono != null)
{
LateUpdateMono();
}
}
/// <summary>
/// FixedUpdate事件
/// </summary>
public event MonoEvent FixedUpdateMono;
void FixedUpdate()
{
if(FixedUpdateMono != null)
{
FixedUpdateMono();
}
}
/// <summary>
/// 当Mono将被销毁时调用
/// </summary>
public event MonoEvent OnDestroyMono;
void OnDestroy()
{
if(OnDestroyMono != null)
{
OnDestroyMono();
}
}
/// <summary>
/// 当被激活时执行的事件
/// </summary>
public event MonoEvent OnEnableMono;
void OnEnable()
{
if(OnEnableMono != null)
{
OnEnableMono();
}
}
/// <summary>
/// 当此GameObject被禁用时被调用
/// </summary>
public event MonoEvent OnDisableMono;
void OnDisable()
{
if(OnDisableMono != null)
{
OnDisableMono();
}
}
#endregion
}
我们可以像UIEventListener中的Get方法那样动态的添加事件到GameObject上,但是,有比他更好的通用的方式。而且我还可以将其通用于UIEventListener类中。我们看以下代码:
using System;
using System.Collections;
using System.Collections.Generic;
using Object = UnityEngine.Object;//使用特定命名空间类的别名
public class Listener
{
#region 为一个Object添加UIMonoEventListener并返回其实例
public static UIMonoEventListener AddUIMonoEvent(Object o)
{
if(o == null)
{
return null;
}
UIMonoEventListener monoEvent = null;
monoEvent = SetMonoEvent(o);
return monoEvent;
}
/// <summary>
/// 获得UnityEngine.Object上的UIMonoEventListener
/// </summary>
/// <param name="o">Unity引擎自己的Object类</param>
/// <returns></returns>
private static UIMonoEventListener SetMonoEvent(Object o)
{
UIMonoEventListener monoEvent = null;
monoEvent = GetMonoEvent(o);
if(monoEvent == null)//分别根据o的类型来为其所在的GameObject动态添加UIMonoEventListener脚本
{
if(o.GetType() == typeof(Transform))
{
monoEvent = (o as Transform).gameObject.AddComponent<UIMonoEventListener>();
}
if(o.GetType() == typeof(GameObject))
{
monoEvent = (o as GameObject).AddComponent<UIMonoEventListener>();
}
if(o.GetType().IsSubclassOf(typeof(MonoBehaviour)))
{
monoEvent = (o as MonoBehaviour).gameObject.AddComponent<UIMonoEventListener>();
}
return monoEvent;
}
return monoEvent;
}
/// <summary>
/// 获得UnityEngine.Object上的UIMonoEventListener
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
private static UIMonoEventListener GetMonoEvent(Object o)
{
UIMonoEventListener monoEvent = null;
if(o.GetType() == typeof(Transform))//如果此对象的类型为Transform
{
monoEvent = (o as Transform).GetComponent<UIMonoEventListener>();
}
if(o.GetType() == typeof(GameObject))
{
monoEvent = (o as GameObject).GetComponent<UIMonoEventListener>();
}
if(o.GetType().IsSubclassOf(typeof(MonoBehaviour)))
{
monoEvent = (o as MonoBehaviour).gameObject.GetComponent<UIMonoEventListener>();
}
return monoEvent;
}
#endregion
}
这样一来,我们就可以对一个名为A的GameObject添加Mono事件了,比如:
Listener. AddUIMonoEvent( A ).UpdateMono += __onUpdate;然后我们可以写一个__OnUpdate的毁掉函数来处理OnUpdate事件,很显然,此回调函数也是每帧执行一次的。好了,我们可以试验一下了,新建一个场景,里面只有两个Cube与一个主摄像机,然后新建一个测试脚本:TestMonoEvent,将其绑定在主摄像机上:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class TestMonoEvent : MonoBehaviour {
public List<GameObject> cubes;
// Use this for initialization
void Start () {
UnityEngine.Object[] gas = FindObjectsOfType(typeof(BoxCollider));//找到带有BoxCollider的这些个类
if(gas == null)
{
return;
}
if(gas.Length == 0)
{
return;
}
foreach (UnityEngine.Object ob in gas)
{
GameObject go = ob as GameObject;
cubes.Add(go);
}
foreach (GameObject go in cubes)
{
if (go.name == "Cube1")
{
Listener.AddUIMonoEvent(go).UpdateMono += new MonoEvent(TestMonoEvent_UpdateMono);
}
else
{
Listener.AddUIMonoEvent(go).StartMono += new MonoEvent(TestMonoEvent_StartMono);
}
}
}
void TestMonoEvent_StartMono()
{
Debug.Log("Start is invoke!");
}
void TestMonoEvent_UpdateMono()
{
Debug.Log("Update is invoke!");
}
}
以上代码非常简单,只是为两个Cube分别添加了UpdateMono事件于StartMono事件,下面我们来运行看看:
成功了,但是,以上事件类还有几个地方需要改进,比如我们订阅事件时,有时需要知道发布事件的对象的引用,那么我们该怎么修改UIMonoEventLisntener类才能满足此需求呢?我想大家应该很快可以对其做出些修改以满足此需求。好了,再见!
|
|