Unity 項目中委托Delegate用法案例


Unity中Delegate的用法場景


本文提供全流程,中文翻譯。

Chinar 堅持將簡單的生活方式,帶給世人!

(擁有更好的閱讀體驗 —— 高分辨率用戶請根據需求調整網頁縮放比例)



Chinar —— 心分享、心創新!

助力快速理解 C# Delegate的基本用法

為新手節省寶貴的時間,避免采坑!


Chinar 教程效果:
這里寫圖片描述



全文高清圖片,點擊即可放大觀看 (很多人竟然不知道)


1

Delegate —— 委托


Unity 中,委托多用於當某個值,或者物體狀態發生改變的時候

其他一些操作需要同時進行監聽

一旦狀態發生,改變,所有注冊在委托中的函數,都會被調用

舉個栗子黑白88
當警察出來的時候,小偷就得逃跑

當服務員叫餐叫號的時候,叫到誰,就該誰取餐

等等,諸如此類的場景


2

Store Model —— 商店模式


這里以一個簡單的 商店模式 來模擬流程

用委托實現,群體的函數、方法注冊到對象中

注意:

我們需要 1 個主腳本用來管理 :服務員

3 個顧客類:顧客 A/B/C

為了更加生動, Chinar 用了 iTween 來處理動畫效果

頁面布局如下
舉個栗子黑白88
這里寫圖片描述
采用委托的方式,通知所有顧客,誰該干什么

分別通知對應群體對象
這里寫圖片描述


3

Waiter —— 服務員腳本


服務員腳本,用於管理委托對象,並在相應的按鈕中調用對象

然后委托對象,狀態發生改變,就會通知所有注冊到對象中的函數,都被調用
舉個栗子黑白88
這里寫圖片描述

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


//委托傳遞的是方法/函數
public delegate void CallNumber(); //使用時,必須要聲明委托對象;返回值類型,要與將要注冊到委托對象中的函數,返回值類型保持一致!


public delegate int GetOuntHandler(); /*也就是:委托方法和被委托方法的類型必須保持一致*/


public delegate bool SomeFood(string food);
/*以上是委托函數的聲明方式*/


/// <summary>
/// Chinar委托測試類
/// </summary>
public class ChinarDelegate : MonoBehaviour
{
    //方法是引用類型的對象
    //委托將一個函數 轉換成了一個函數對象
    //可以將 這個函數 以 對象 的形式進行傳遞
    public CallNumber callNumber;  //定義委托對象 這里定義的是一個委托對象
    public SomeFood   someFood;    //定義一個有參數有返回值的委托
    public Text       WaiterSpeak; //服務員說話內容文本
    public Text       BigScreen;   //服務員說話內容文本
    public GameObject G2GameObject;

    /// <summary>
    /// 叫號方法 —— 綁定按鈕
    /// </summary>
    public void OnClickCallNumber()
    {
        callNumber();
        Content(Color.red, "叫號啦!!!", "請100號顧客取餐!");
    }


    /// <summary>
    /// 漢堡包 —— 綁定按鈕
    /// </summary>
    public void OnClickHamburger()
    {
        if (!GameObject.Find("Hamburger(Clone)")) Instantiate(Resources.Load("Hamburger"));
        someFood("漢堡");
        Content(UserTwo.temporaryText.color, "誰的漢堡?", "請B號顧客取餐!");
    }


    /// <summary>
    /// 可樂 —— 綁定按鈕
    /// </summary>
    public void OnClickCola()
    {
        someFood("可樂");
        Content(UserTwo.temporaryText.color, "誰點的可樂?", "請C號顧客取餐!");
    }


    /// <summary>
    /// 封裝內容簡化代碼
    /// </summary>
    /// <param name="color"></param>
    /// <param name="speak"></param>
    /// <param name="bigScreen"></param>
    private void Content(Color color, string speak, string bigScreen)
    {
        WaiterSpeak.text  = speak;
        WaiterSpeak.color = color;
        BigScreen.text    = bigScreen;
        StopCoroutine(ClearText());
        StartCoroutine(ClearText());
    }


    /// <summary>
    /// 清理文本內容
    /// </summary>
    /// <returns></returns>
    IEnumerator ClearText()
    {
        yield return new WaitForSeconds(3);
        WaiterSpeak.text = "";
        BigScreen.text   = "";
    }


    public static void Move(GameObject gameObject)
    {
        iTween.MoveTo(gameObject, iTween.Hash("time",                                     .7f, "x",     6.69f,                         "y",        8.6f, "easetype", iTween.EaseType.easeOutCubic));
        iTween.MoveTo(gameObject, iTween.Hash("time",                                     .7f, "x",     -13.38f,                       "y",        2.8f, "easetype", iTween.EaseType.easeOutCubic, "delay", 2.4f));
        iTween.ScaleTo(gameObject.transform.Find("Speak").gameObject, iTween.Hash("time", .7f, "scale", new Vector3(0.3f, 0.3f, 0.3f), "easetype", iTween.EaseType.easeOutCubic));
        iTween.ScaleTo(gameObject.transform.Find("Speak").gameObject, iTween.Hash("time", .7f, "scale", new Vector3(1,    1,    1),    "easetype", iTween.EaseType.easeOutCubic, "delay", 2.4f));
        iTween.ScaleTo(gameObject,                                    iTween.Hash("time", .7f, "scale", new Vector3(3,    3,    3),    "easetype", iTween.EaseType.easeOutCubic));
        iTween.ScaleTo(gameObject,                                    iTween.Hash("time", .7f, "scale", new Vector3(1,    1,    1),    "easetype", iTween.EaseType.easeOutCubic, "delay", 2.4f));
        iTween.RotateTo(gameObject, iTween.Hash("time",                                   .7f, "z",     -360.01f,                      "easetype", iTween.EaseType.easeOutCubic));
    }
}

4

Client A/B/C Class —— 顧客A/B/C腳本


3 個顧客類:顧客 A/B/C
舉個栗子黑白88
這里寫圖片描述

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


/// <summary>
/// 顧客A
/// </summary>
public class UserOne : MonoBehaviour
{
    public  ChinarDelegate Cd;            //聲明委托對象所在的類對象//實例化一個類對象 在內存中重新開辟一塊內存空間 創建了一個新的類對象
    public static Text temporaryText; //臨時文本,設置公有靜態是為了 方便調用顏色屬性,去改變服務員文本顏色



    void Start()
    {
        Cd            = GameObject.Find("MountScript").GetComponent<ChinarDelegate>(); //賦值
        Cd.callNumber += LookScreen;
        temporaryText = transform.Find("Speak/Text").GetComponent<Text>();

        //添加委托函數
        //委托函數的添加方式:可以用 = 號 
        //如果想添加多個委托 需要用 +=號
        //刪除委托用: -=
    }


    /// <summary>
    /// 抬頭看大屏幕
    /// </summary>
    public void LookScreen()
    {
        temporaryText.text = "顧客A看向大屏幕";
        StopCoroutine(ClearText());
        StartCoroutine(ClearText());
    }


    /// <summary>
    /// 清理文本內容
    /// </summary>
    /// <returns></returns>
    IEnumerator ClearText()
    {
        yield return new WaitForSeconds(3);
        temporaryText.text = "";
    }
}

顧客 B:

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


/// <summary>
/// 顧客B
/// </summary>
public class UserTwo : MonoBehaviour
{
    public        ChinarDelegate Cd;
    public static Text           temporaryText; //臨時文本,設置公有靜態是為了 方便調用顏色屬性,去改變服務員文本顏色


    void Start()
    {
        Cd            =  GameObject.Find("MountScript").GetComponent<ChinarDelegate>();
        Cd.callNumber += LookScreen; //2添加委托函數
        Cd.someFood   += WaitHamburger;
        temporaryText =  transform.Find("Speak/Text").GetComponent<Text>();
    }


    /// <summary>
    /// 服務員叫漢堡時,委托事件才會觸發
    /// </summary>
    public bool WaitHamburger(string food)
    {
        if (food == "漢堡")
        {
            temporaryText.text = "這里,我要漢堡";
            ChinarDelegate.Move(gameObject);
            iTween.MoveTo(GameObject.Find("Hamburger(Clone)"), iTween.Hash("oncomplete", "DestroyHamburger", "oncompletetarget", gameObject,           "time",     .7f,                          "x",     -13.38, "y", 2.8f, "easetype", iTween.EaseType.easeOutCubic, "delay", 2.4f));
            iTween.ScaleTo(GameObject.Find("Hamburger(Clone)"), iTween.Hash("time",      .7f,                "scale",            new Vector3(0, 0, 0), "easetype", iTween.EaseType.easeOutCubic, "delay", 2.4f));

            StopCoroutine(ClearText());
            StartCoroutine(ClearText());
            return true;
        }
        return false;
    }


    private void DestroyHamburger()
    {
        Destroy(GameObject.Find("Hamburger(Clone)"));
    }


    /// <summary>
    /// 抬頭看大屏幕
    /// </summary>
    public void LookScreen()
    {
        temporaryText.text = "顧客B看向大屏幕";
        StopCoroutine(ClearText());
        StartCoroutine(ClearText());
    }


    /// <summary>
    /// 清理文本內容
    /// </summary>
    /// <returns></returns>
    IEnumerator ClearText()
    {
        yield return new WaitForSeconds(3);
        temporaryText.text = "";
    }
}

顧客 C:

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


/// <summary>
/// 顧客C
/// </summary>
public class UserThree : MonoBehaviour
{
    public        ChinarDelegate Cd;            //委托對象
    public static Text           temporaryText; //臨時文本,設置公有靜態是為了 方便調用顏色屬性,去改變服務員文本顏色


    void Start()
    {
        Cd            =  GameObject.Find("MountScript").GetComponent<ChinarDelegate>(); //獲取對象
        Cd.callNumber += LookScreen;                                                    //當 叫號的委托對象中,有多個方法調用時,需要用 += 添加
        Cd.someFood   += WaitCola;                                                      //委托對象添加 顧客3的可樂
        temporaryText =  transform.Find("Speak/Text").GetComponent<Text>();
    }


    /// <summary>
    /// 服務員叫可樂時,委托事件才會觸發
    /// </summary>
    public bool WaitCola(string food)
    {
        if (food == "可樂")
        {
            temporaryText.text = "這里,我要的可樂";
            ChinarDelegate.Move(gameObject);
            StopCoroutine(ClearText());
            StartCoroutine(ClearText());
            return true;
        }

        return false;
    }


    /// <summary>
    /// 抬頭看大屏幕
    /// </summary>
    public void LookScreen()
    {
        temporaryText.text = "顧客C看向大屏幕";
        StopCoroutine(ClearText());
        StartCoroutine(ClearText());
    }


    /// <summary>
    /// 清理文本內容
    /// </summary>
    /// <returns></returns>
    IEnumerator ClearText()
    {
        yield return new WaitForSeconds(3);
        temporaryText.text = "";
    }
}

5

Demo —— 演示樣本


Chinar 提供了演示樣本,節省大家搭建界面的時間

便於大家理解
舉個栗子黑白88

Chinar 委托演示項目


支持

May Be —— 搞開發,總有一天要做的事!


擁有自己的服務器,無需再找攻略!

Chinar 提供一站式教程,閉眼式創建!

為新手節省寶貴時間,避免采坑!


先點擊領取 —— 阿里全產品優惠券 (享受最低優惠)


1 —— 雲服務器超全購買流程 (新手必備!)

2 —— 阿里ECS雲服務器自定義配置 - 購買教程(新手必備!)

3—— Windows 服務器配置、運行、建站一條龍 !

4 —— Linux 服務器配置、運行、建站一條龍 !





技術交流群:806091680 ! Chinar 歡迎你的加入


END

本博客為非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究

對於需要復制、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯系,留言,Email: ichinar@icloud.com

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM