我正在使用Unity制作游戏并为其创建一个简单的事件系统。该系统允许使用回调委托订阅事件。
系统代码在这里:
public static class Events {
#region fields
public delegate void EventCallback();
public static Dictionary<Event, EventCallback> events;
public enum Event {
PlayerDied,
EnterGoal,
ExitGoal
}
#endregion
static Events() {
Reset();
}
public static void Reset() {
events = new Dictionary<Event, EventCallback>();
}
public static void SubscribeToEvent(EventCallback callback, Event type) {
if (!events.ContainsKey(type)) {
events.Add(type, callback);
} else {
events[type] += callback;
}
}
public static void OverrideSubscription(EventCallback callback, Event type) {
if (!events.ContainsKey(type)) {
events.Add(type, callback);
} else {
events[type] = callback;
}
}
public static void UnsubscribeFromEvent(EventCallback callback, Event type) {
if (events.ContainsKey(type)) {
events[type] -= callback;
}
}
public static void FireEvent(Event type) {
if (!events.ContainsKey(type)) {
return;
}
events[type]?.Invoke();
}
}
我的问题是这样
在游戏中,订阅某个事件的对象经常会被销毁(因此无效),但回调仍被调用。
为了证明这一点,我为此进行了测试。以下2个测试失败。
[Test]
public void CallbackIsNotCalledAfterReassigning() {
Events.SubscribeToEvent(callbacks.A, Events.Event.PlayerDied);
// Reassign
callbacks = new CallbackContainer();
Events.FireEvent(Events.Event.PlayerDied);
Assert.AreEqual(0, callbacks.a, "Test function was called after reassigning");
Assert.AreEqual(0, a, "Old instance method is still being called");
}
[Test]
public void CallbackIsNotCalledAfterNullifying() {
Events.SubscribeToEvent(callbacks.A, Events.Event.PlayerDied);
// Nullify
callbacks = null;
Events.FireEvent(Events.Event.PlayerDied);
Assert.AreEqual(0, a, "Test function was not called");
}
而CallbackContainer类在这里:
public class CallbackContainer {
public int a, b, c;
public CallbackContainer() {
int a = 0;
int b = 0;
int c = 0;
}
public Action TestFunction;
public void A() {
EventsTest.a++;
a++;
}
public void B() {
EventsTest.b++;
b++;
}
public void C() {
EventsTest.c++;
c++;
}
}
是否有解决此问题的方法?有没有更好,更正确的方法来创建事件系统?
任何帮助或建议都值得赞赏。
答案 0 :(得分:0)
我忘记了Unity自己的委托OnDestroy,该委托在对象取消样式化或加载另一个场景之前被调用。