Unity 使用AddListener监听事件与取消监听

Unity中,有时候我们会动态监听组件中的某个事件。当我们使用代码动态加载多次,每次动态加载后我们会发现原来的和新的事件都会监听,如若我们只想取代原来的监听事件,那么就需要取消监听再添加监听了。

如实现如下需求:

如果我们这样编写控制代码:

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class DynamicDetection : MonoBehaviour
{
    public Button button1;
    public Button button2;
    public TextMeshProUGUI text;
    int index;
    // Start is called before the first frame update
    void Start()
    {
        index = 0;
        button1.onClick.AddListener(delegate
        {
            index++;
            button2.GetComponentInChildren<TextMeshProUGUI>().text = index.ToString();
            button2.onClick.AddListener(SetVal);
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void SetVal()
    {
        Debug.Log("来了");
        text.text = "交互了" +  button2.GetComponentInChildren<TextMeshProUGUI>().text +"次";
    }
   
}

运行后我们会发现如下情况:

这明显跟我们需求(每次动态加载都只监听最新的事件)是不一致的。

正确的做法是先取消原来监听再重新监听。

如下:

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class DynamicDetection : MonoBehaviour
{
    public Button button1;
    public Button button2;
    public TextMeshProUGUI text;
    int index;
    // Start is called before the first frame update
    void Start()
    {
        index = 0;
        button1.onClick.AddListener(delegate
        {
            index++;
            button2.GetComponentInChildren<TextMeshProUGUI>().text = index.ToString();
            button2.onClick.RemoveListener(SetVal);
            //button2.onClick.RemoveAllListeners();
            button2.onClick.AddListener(SetVal);
        });
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void SetVal()
    {
        Debug.Log("来了");
        text.text = "交互了" +  button2.GetComponentInChildren<TextMeshProUGUI>().text +"次";
    }
   
}

此处我们可以使用两个方法取消监听,其中一个是RemoveListener方法。不过使用该方法需要注意的是:取消监听的方法需要与之前添加的监听方法相同,否则取消操作将不起作用。

另外我们还可以使用RemoveAllListeners方法。这个方法可以移除指定事件上的所有监听器,而不需要逐个指定要移除的监听器。

相关推荐
鼎艺创新科技4 小时前
不依赖 UE/Unity:我们如何从零搭建一套国产三维 GIS 渲染引擎
人工智能·算法·unity·游戏引擎·三维电子沙盘
新手unity自用笔记12 小时前
unity基于Socket的网络学习
网络·网络协议·学习·unity·c#·游戏引擎
心前阳光14 小时前
Unity之XR Interaction Toolkit | IPointerDownHandler问题
unity·游戏引擎·xr
帅_shuai_2 天前
unity 静态字段内存查找工具
unity·游戏引擎
郝学胜-神的一滴2 天前
[简化版 GAMES 104] 现代游戏引擎 06:从Tick时序到邮局模型,拆解确定性世界的底层密码
开发语言·c++·游戏引擎·图形渲染·软件开发·opengl
鹿野素材屋3 天前
Unity超轻量级中文语音播报,仅5兆大小,无需联网即可使用,适用于弹幕、提示等动态语音播出
unity·游戏引擎
电子云与长程纠缠4 天前
UE5 Lyra PocketWorld进行3D内容UI预览 - 上
开发语言·学习·3d·ue5·游戏引擎
玖玥拾4 天前
Unity3D RPG 入门项目(八)游戏设置面板、帧率控制、快捷技能药品栏、技能解锁系统
游戏·3d·unity·游戏引擎
ellis19704 天前
u3d插件xLua[十] lua侧判空问题
unity
牛哇网络工作室4 天前
UnityHDRP写实数字人全流程基础5—语音输入和语音识别
android·unity·c#·游戏引擎·aigc·语音识别·xcode