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方法。这个方法可以移除指定事件上的所有监听器,而不需要逐个指定要移除的监听器。

相关推荐
不吃凉粉16 小时前
Unity与AS通信
unity·游戏引擎
两水先木示1 天前
【Unity】探索小地图迷雾散开Shader效果(基础版)
unity·游戏引擎
WarrenMondeville1 天前
AI复刻街头霸王到 Unity
unity·游戏引擎
玖玥拾2 天前
Lua 基础语法(六)xLua Lua 调用 C# 交互
开发语言·unity·c#·lua
xcLeigh2 天前
Unity基础:MonoBehaviour的生命周期——Awake、OnEnable、Start、Update执行顺序
unity·游戏引擎
qq_213157892 天前
其域lcc2丢失部分lod/远处显示空洞的解决方式
unity·lcc2
辻弋2012 天前
自动检测硬件生成驱动清单、实时监控FPS、120秒性能记录——30+项优化模块化开关,所有改动可精确复原
服务器·windows·游戏引擎·电脑·开源软件
点心的游戏开发世界2 天前
GDScript 入门笔记:目录
开发语言·笔记·游戏引擎·godot
XR技术研习社2 天前
关于 PICO 串流测试中报错 IndexOutOfRangeException: renderPassIndex 的两个排障方法
unity·ar·xr·vr
想做后端的前端2 天前
Unity · 性能优化:内存管理完全指南:从托管堆到跨桥开销
unity·性能优化·游戏引擎