也许这不是最好的标题,但我不知道该怎么说。
我有一个问题/好奇心,在任何地方都找不到更好的解决方案。
我正在开发一个Unity游戏,假设我有一个类,在其中声明一个事件并调用它
ClassA : MonoBehaviour
public static event Action<string> LevelCompletedEvent;
public void LevelCompleted()
{
LevelCompletedEvent?.Invoke("Good job!");
}
我想在其他两个类中使用此事件,以侦听它。
在ClassB中,我使用参数在UI中输出消息。
ClassB : MonoBehaviour
OnEnable(){
ClassA.LevelCompletedEvent += DisplayMessage;
}
OnDisable(){
ClassA.LevelCompletedEvent -= DisplayMessage;
}
private void DisplayMessage(string message)
{
//display the message in the UI
}
然而,在ClassC中,我不需要传入参数“message”。我只需要知道活动已经完成。
ClassC : MonoBehaviour
OnEnable(){
ClassA.LevelCompletedEvent += PlaySound;
}
OnDisable(){
ClassA.LevelCompletedEvent -= PlaySound;
}
private void PlaySound()
{
//play a sound
}
问题是它不允许我订阅事件,因为处理程序没有相同的签名。所以我尝试使用匿名委托订阅它。
ClassC
OnEnable(){
ClassA.LevelCompletedEvent += delegate { PlaySound(); };
}
OnDisable(){
ClassA.LevelCompletedEvent -= delegate { PlaySound(); };
}
看到这一点,我经常使用这种方法,但最近了解到它实际上并没有从匿名代理那里退订,我应该保留对它的引用。
所以我改成
ClassC
private Action<string> LevelCompletedNewDelegate;
OnEnable(){
LevelCompletedNewDelegate = delegate { PlaySound(); };
ClassA.LevelCompletedEvent += LevelCompletedNewDelegate;
}
OnDisable(){
ClassA.LevelCompletedEvent -= LevelCompletedNewDelegate;
}
现在这是可行的,但我不确定这是否是最好的方法。
我有很多事件,我真的不喜欢这样,我必须在监听器方面声明一个新的动作委托。
有没有更好的方法?
我发现的最简单的方法是创建一个新的操作事件并为ClassC调用它,如:
ClassA : MonoBehaviour
public static event Action<string> LevelCompletedEvent;
public static event Action LevelCompletedPlaySound;
public void LevelCompleted()
{
LevelCompletedEvent?.Invoke("Good job!"); //used by ClassB
LevelCompletedPlaySound?.Invoke(); //used by ClassC
}
这样,我可以为每节课都安排一个活动,但我不确定这样是否更好。感觉有点多余。你觉得怎么样?
很抱歉给你发了这么长的信息,但也许这可以帮助其他正在为此挣扎的人也能理解。
非常感谢。