在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 updatevoid Start(){index = 0;button1.onClick.AddListener(delegate{index++;button2.GetComponentInChildren<TextMeshProUGUI>().text = index.ToString();button2.onClick.AddListener(SetVal);});}// Update is called once per framevoid 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 updatevoid 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 framevoid Update(){}public void SetVal(){Debug.Log("来了");text.text = "交互了" + button2.GetComponentInChildren<TextMeshProUGUI>().text +"次";}}
此处我们可以使用两个方法取消监听,其中一个是RemoveListener
方法。不过使用该方法需要注意的是:取消监听的方法需要与之前添加的监听方法相同,否则取消操作将不起作用。
另外我们还可以使用RemoveAllListeners
方法。这个方法可以移除指定事件上的所有监听器,而不需要逐个指定要移除的监听器。