委託-事件的運用教程詳解-中文遊戲示例!(非常適合初學者學習)

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]

對於經本博主明確授權和許可使用文章及內容的,使用時請註明文章或內容出處並註明網址

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