美文网首页UnityUnity技术分享征服Unity3d
Jtro的技术分享:unity中使用事件与委托加单例

Jtro的技术分享:unity中使用事件与委托加单例

作者: UnityPlane | 来源:发表于2017-09-09 14:36 被阅读163次

    在unity开发中,如果你频繁的使用bool值判断,代码臃肿繁琐,请立即停止它!有的时候用一些简单的办法就可以得到你以前几百行代码的效果。

    鄙人尽量用简单的例子来说明问题,让有编程功底的人简明扼要的明白。

    那么,什么情况下要用到事件和委托呢?

    请看下面的场景:一辆公交车上,乘客A要在第二站下车,乘客B要在第三站下车,乘客到哪下车,公交车不关心。

    有的同学会用if判断语句:

    ```

    if (到了第二站)

    {

    乘客A下车;

    }

    if (到了第三站)

    {

    乘客B下车;

    }

    ```

    ...........

    这样的逻辑是没有任何问题的,但是需求是:车上的人下车地点都不一样,上面的代码就会无限制的扩充。严重破坏代码的封装性。显然这不是我们希望的。

    真确的方法应该是:公交车不管有多少人,只发出到站的信息,乘客到了站台,自己下车就好了。

    创建一个Bus脚本,编辑如下:

    ```

    //    脚本功能:

    //此脚本挂载在:    上

    //    初创日期:

    //        作者:张曙光

    //  第一次修改:

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    public class _Bus : MonoBehaviour {

    /// 公交车到站的委托

    public delegate void StationEventHandler (int num);//这是一个无返回值有参数的委托

    /// 公交车到站的事件

    public event  StationEventHandler onStation;//可以加减方法体

    int num = 0;//当前的站台号

    void Awake ()

    {

    this.onStation += GetOFF;

    }

    // Use this for initialization

    void Start () {

    }//End of Start

    // Update is called once per frame

    void Update () {

    //按下A键就表示到下一站

    if (Input .GetKeyDown (KeyCode.A ))

    {

    num++;

    if(num <10)

    {

    Station (num);//调用方法,传参数

    }

    }

    }//End of Update

    public void Station (int num)

    {

    Debug.Log (num +" 号站台到了");

    //调用到站事件,传入站号作为参数

    if(onStation != null)

    {

    onStation (num);

    }

    }

    void GetOFF ( int num )

    {

    if (num == 2)

    {

    Debug.Log ("2号乘客下车");

    this.onStation -= GetOFF;

    }

    }

    }

    ```

    创建PassengerA脚本,编辑如下:

    ```

    //    脚本功能:

    //此脚本挂载在:    上

    //    初创日期:

    //        作者:张曙光

    //  第一次修改:

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    public class PassengerA : MonoBehaviour {

    public _Bus bus;//声明带有委托的脚本

    void Awake ()

    {

    bus.onStation += Getoff;//这样加方法也是可以的

    //bus.onStation += new _Bus.StationEventHandler(Getoff);

    }

    void Getoff (int num)

    {

    if (num == 2)

    {

    Debug.Log ("乘客A在2号站台下车");

    //下车之后取消监听公交车到站事件

    bus.onStation -= Getoff;

    }

    }

    }

    ```

    创建PassengerB脚本,编辑如下:

    ```

    //    脚本功能:

    //此脚本挂载在:    上

    //    初创日期:

    //        作者:张曙光

    //  第一次修改:

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    public class PassengerB : MonoBehaviour {

    public _Bus bus;//声明带有委托的脚本

    void Awake ()

    {

    bus.onStation += new _Bus.StationEventHandler (Getoff);

    }

    void Getoff (int num)

    {

    if (num == 3)

    {

    Debug.Log ("乘客B在3号站台下车");

    //下车之后取消监听公交车到站事件

    bus.onStation -= Getoff;

    }

    }

    }

    ```

    在unity中创建3个空对象并命名为:bus,PassengerA,PassengerB,然后将3个脚本分别挂载在上面。运行结果如下图:

    运行结果

    单例:单例就是单个的意思,保证在游戏运行的时候不会有第二个自己存在,一般的解释就是:保证一个类只有一个实例,并提供访问它的全局访问点。一般的,在游戏中UI 用到的最多,当然,小怪也用的比较多。

    实现的方式:

    ```

    //    脚本功能:单利

    //此脚本挂载在:    上

    //    初创日期:

    //        作者:张曙光

    //  第一次修改:

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    public class Single : MonoBehaviour {

    public int num = 10;

    //单利开始

    public static Single instance;

    public void Awake ()

    {

    if (instance == null)

    {

    instance = this;

    }

    }

    public string showmsg ()

    {

    return "我是单例";

    }

    }

    ```

    访问单例:

    ```

    //    脚本功能:

    //此脚本挂载在:    上

    //    初创日期:

    //        作者:张曙光

    //  第一次修改:

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    public class visitSigle : MonoBehaviour {

    // Use this for initialization

    void Start () {

    int n = Single.instance.num;

    string str = Single.instance.showmsg ();

    Debug.Log ("n: "+n +" sting: "+str);

    }//End of Start

    // Update is called once per frame

    void Update () {

    }//End of Update

    }

    ```

    新建一个空物体,两个脚本都挂上,运行:

    单例运行结果

    优点:不需要重构,直接编码,其他类或者脚本直接使用

    缺点:需要把实现单例的类手动绑定到游戏对象上才可以使用

    OK,这两个简单的技能学到了以后会比你以前只用bool值判断的的编码轻松不少吧。感谢简书!感谢读完的你!

    相关文章

      网友评论

        本文标题:Jtro的技术分享:unity中使用事件与委托加单例

        本文链接:https://www.haomeiwen.com/subject/sroojxtx.html