委托-事件的运用教程详解-中文游戏示例!(非常适合初学者学习)

Chinar blog www.chinar.xin

委托教程-实例说明


本文提供全流程,中文翻译

助力理解 Delegate 委托的实际应用

为初学者节省宝贵的时间,避免采坑!

Chinar —— 心分享、心创新!

我们的初衷是将一种简单的生活方式带给世人

使有限时间 具备无限可能

Chinar 教程效果:



全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

Intro —— 简介


委托的设计机制,导致了很多初学者在学习初期很难理解它究竟是什么?到底该怎么用,干什么用?

大家都知道,Chinar 不喜欢把那些繁杂的概念知识,复制粘贴过来告诉初学者。
那不能证明我有多厉害,无法将知识简化传授给大家,那只能证明我有多无能。

言归正传,我们先来看下字面意思

委托 (字典解释) :把事情托付给别人或别的机构办理

先记住字面意义,通过下边的讲解,你会逐渐理解委托。


2

Event —— 事件


先来说一个比较好理解的,委托的另一种类型: 事件 /Event

示例 1:
大家听过广播吧?

FM98.7、92.5、95.6不同的频道,播放着不同的节目
你听不听广播,每个频道都在一直的播放着节目给各位听众
只有调到对应频道的人,才能听到广播
不在频道上的,听不到广播。不打开收音机的人,也听不到广播

  • 电台,只管发送广播
  • 用户,只管订阅对应频道,就能听到节目广播内容

示例 2:
都玩过游戏吧?

那一定对系统通知、帮派通知,地区通知、以及其他形式的定向通知有印象吧?
系统通知:下发给所有玩家
帮派通知:下发给本帮内玩家
地区通知:下发给当前地区内玩家

  • 系统,发出去消息
  • 用户,订阅系统通知、帮派通知、地区通知 等各种通知

总结:
一方负责发布信息
而这些发布出去的事件,一方来根据需求选择性订阅。

这就是事件/Event 的发布、订阅机制

发布代码

using System;
using UnityEngine;


/// <summary>
/// 事件发布管理器
/// </summary>
public class ChinarObservable : MonoBehaviour
{
    /// <summary>
    /// 单例
    /// </summary>
    public static ChinarObservable Self => self ?? (self = FindObjectOfType<ChinarObservable>());
    private static ChinarObservable self;

    /// <summary>
    /// 系统通知
    /// </summary>
    public event Action<string> SystemNotice;
    /// <summary>
    /// 帮派通知
    /// </summary>
    public event Action<int, string> Faction;


    private ChinarUI ui; //引用UI对象


    void Start()
    {
        ui = FindObjectOfType<ChinarUI>();
    }


    /// <summary>
    /// 系统消息——通知所有玩家
    /// 通过事件,通知所有订阅事件的玩家。
    /// </summary>
    /// <param name="message">消息内容</param>
    public void Send_SystemNotification(string message)
    {
        ui.UpdateLargeScreenText("系统通知:" + message);
        SystemNotice?.Invoke(message); //
    }


    /// <summary>
    /// 群发信息——通知对应帮派玩家
    /// </summary>
    /// <param name="factionId">帮派编号</param>
    /// <param name="message">消息内容</param>
    public void Send_FactionNotification(int factionId, string message)
    {
        ui.UpdateLargeScreenText($"{factionId}号帮派通知:{message}");
        Faction?.Invoke(factionId, message);
    }
}

订阅代码

using System.Collections;
using UnityEngine;
using UnityEngine.UI;


/// <summary>
/// 玩家总类
/// </summary>
public class ChinarPlayer : MonoBehaviour
{
    public  int  FactionId = 0; //玩家帮派ID编号
    private Text messageText;   //玩家自身,消息提示框 (仅作为例子设计,正常游戏中并不这么设计)


    void Start()
    {
        ChinarObservable.Self.SystemNotice += SubscribeSystemNotice; //对发布的事件进行订阅
        ChinarObservable.Self.Faction      += SubscribeFaction;      //订阅你想订阅的事件
        messageText                        =  transform.Find("Speak/Text").GetComponent<Text>();
    }


    /// <summary>
    /// 虚方法的设计,是为了便于子类中对现有方法进行扩展
    /// 订阅帮派信息
    /// </summary>
    protected virtual void SubscribeFaction(int factionId, string message)
    {
        if (FactionId == factionId)
        {
            StopAllCoroutines();
            StartCoroutine(ShowNotice($"{factionId}号帮,{message}"));
        }
    }


    /// <summary>
    /// 订阅系统信息
    /// </summary>
    protected virtual void SubscribeSystemNotice(string message)
    {
        StopAllCoroutines();
        StartCoroutine(ShowNotice($"系统提示:{message}"));
    }


    /// <summary>
    /// 显示通知,并在2秒后关闭(清空信息)
    /// </summary>
    /// <param name="arg">通知内容</param>
    IEnumerator ShowNotice(string arg)
    {
        messageText.text = arg;
        yield return new WaitForSeconds(2f);
        messageText.text = string.Empty;
    }
}

UI层引用

using UnityEngine;
using UnityEngine.UI;


/// <summary>
/// UI层
/// </summary>
public class ChinarUI : MonoBehaviour
{
    private Button     systemButton;     //系统按钮
    private Button     faction1Button;   //帮派1按钮
    private Button     faction2Button;   //帮派2按钮
    private InputField systemInputField; //系统输入框
    private Text       largeScreenText;  //大屏幕文本框


    void Start()
    {
        systemButton     = transform.Find("System Button").GetComponent<Button>();
        systemInputField = transform.Find("InputField").GetComponent<InputField>();
        faction1Button   = transform.Find("Faction1 Button").GetComponent<Button>();
        faction2Button   = transform.Find("Faction2 Button").GetComponent<Button>();
        largeScreenText  = GameObject.Find("Large Screen/Text").GetComponent<Text>();
        systemButton.onClick.AddListener(() => ChinarObservable.Self.Send_SystemNotification(systemInputField.text));
        faction1Button.onClick.AddListener(() => ChinarObservable.Self.Send_FactionNotification(1, systemInputField.text));
        faction2Button.onClick.AddListener(() => ChinarObservable.Self.Send_FactionNotification(2, systemInputField.text));
    }


    /// <summary>
    /// 更新大屏幕信息
    /// </summary>
    /// <param name="message">信息内容</param>
    public void UpdateLargeScreenText(string message)
    {
        largeScreenText.text = message;
    }
}

2

Event —— 事件


Unity 版本:2018.4.11

项目文件为 unitypackage 文件包:

下载导入 Unity 即可使用


支持

May Be —— 开发者,总有一天要做的事!


拥有自己的服务器,无需再找攻略

Chinar 提供一站式《零》基础教程

使有限时间 具备无限可能!

先点击领取 —— 阿里全产品优惠券 (享受最低优惠)


Chinar 免费服务器、建站教程全攻略!( Chinar Blog )


Chinar

END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: [email protected]

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章