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

相关推荐
程序员正茂8 小时前
Unity3d使用MQTT异步连接服务端
mqtt·unity·异步
mxwin9 小时前
在unity shader中,通过pass产生阴影,通过主pass的光照 接收阴影!那么问题来了,是先产生阴影吗?还是先接收阴影,执行顺序是啥呢
数码相机·unity·游戏引擎·shader
小贺儿开发10 小时前
《唐朝诡事录之长安》——盛世马球
人工智能·unity·ai·shader·绘画·影视·互动
蒙双眼看世界19 小时前
Unity结合ECharts图表及网页插件EmbeddedBrowser的应用开发
unity·游戏引擎·echarts
郝学胜-神的一滴1 天前
中级OpenGL教程 004:为几何体注入法线灵魂
c++·unity·游戏引擎·godot·图形渲染·opengl·unreal
la_vie_est_belle2 天前
Pygame Studio——用Python自制的一款可视化游戏编辑器
python·游戏·编辑器·游戏引擎·pygame·pyside6·pygame-ce
LF男男3 天前
GameManager.cs
unity
晴夏。3 天前
c++调用lua的方法
c++·游戏引擎·lua·ue
RPGMZ4 天前
RPGMakerMZ 地图存档点制作 标题继续游戏直接读取存档
开发语言·javascript·游戏·游戏引擎·rpgmz·rpgmakermz
郝学胜-神的一滴4 天前
[简化版 GAMES 101] 计算机图形学 07:图形学投影完全推导
c++·unity·图形渲染·three.js·unreal engine