12 第1页 | 共2 页下一页
返回列表 发新帖
查看: 6125|回复: 12
打印 上一主题 下一主题

[教程] Unity中的事件编程2

[复制链接]

21

主题

7

听众

651

积分

初级设计师

Rank: 3Rank: 3

纳金币
0
精华
3

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2013-4-16 20:39:20 |只看该作者 |倒序浏览
      上一篇我介绍了从一个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事件,下面我们来运行看看:
1.png
成功了,但是,以上事件类还有几个地方需要改进,比如我们订阅事件时,有时需要知道发布事件的对象的引用,那么我们该怎么修改UIMonoEventLisntener类才能满足此需求呢?我想大家应该很快可以对其做出些修改以满足此需求。好了,再见!




分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

955

主题

164

听众

7万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
59338
精华
28

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

沙发
发表于 2013-4-16 21:15:20 |只看该作者

回帖奖励 +1

很不错的介绍,希望继续分享NGUI更多的教程!
回复

使用道具 举报

21

主题

7

听众

651

积分

初级设计师

Rank: 3Rank: 3

纳金币
0
精华
3

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2013-4-16 21:30:01 |只看该作者
恩,一定一定。
回复

使用道具 举报

0

主题

1

听众

7

积分

设计初学者

Rank: 1

纳金币
4
精华
0

活跃会员 灌水之王

地板
发表于 2013-4-17 08:59:55 |只看该作者
顶楼主,太好看了~~~~~~~~~~
回复

使用道具 举报

2

主题

9

听众

6387

积分

高级设计师

Rank: 6Rank: 6

纳金币
881
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2013-4-17 09:15:48 |只看该作者
感谢楼主的分享
回复

使用道具 举报

ling    

19

主题

7

听众

1467

积分

助理设计师

Rank: 4

纳金币
1220
精华
1

活跃会员

6#
发表于 2013-4-17 12:20:38 |只看该作者

感谢楼主的分享
回复

使用道具 举报

Sora    

0

主题

1

听众

86

积分

设计初学者

Rank: 1

纳金币
4
精华
0

活跃会员 灌水之王

7#
发表于 2013-4-28 09:15:52 |只看该作者
好棒的教學呀 !!
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

8#
发表于 2013-6-2 21:34:21 |只看该作者
顶一个,支持楼主的教程!
回复

使用道具 举报

20

主题

5

听众

1090

积分

助理设计师

Rank: 4

纳金币
105
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

9#
发表于 2013-6-28 11:11:52 |只看该作者
楼主的教程一直很好
回复

使用道具 举报

12

主题

2

听众

657

积分

初级设计师

Rank: 3Rank: 3

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

10#
发表于 2013-6-28 11:46:20 |只看该作者
专业啊,不错的教程
回复

使用道具 举报

12 第1页 | 共2 页下一页
返回列表 发新帖
您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-4-26 19:20 , Processed in 0.099927 second(s), 35 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部