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