我来自这篇文章
https://unity3d.com/how-to/architect-with-scriptable-objects
,并想知道如何引发事件并将数据传递给它。因为仅仅听这个事件是不够的。我将尽力解释它以便复制。
首先,我创建了一个新的游戏事件 LevelSceneLoadedGameEvent
class LevelSceneLoadedGameEvent : UnityEvent<Scene> { }
引发此事件时,它应该返回已加载的当前场景。接下来,我创建了一个静态的 EventManager 来管理所有这些事件
public static class EventManager
{
private static Dictionary<Type, UnityEvent> events = new Dictionary<Type, UnityEvent>()
{
{
typeof(LevelSceneLoadedGameEvent),
new LevelSceneLoadedGameEvent()
}
};
private static UnityEvent GetEvent<EventType>() where EventType : UnityEvent
{
return events[typeof(EventType)];
}
public static void SubscribeTo<EventType>(UnityAction listener) where EventType : UnityEvent
{
GetEvent<EventType>().AddListener(listener);
}
public static void UnsubscribeFrom<EventType>(UnityAction listener) where EventType : UnityEvent
{
GetEvent<EventType>().RemoveListener(listener);
}
public static void Trigger<EventType>() where EventType : UnityEvent
{
GetEvent<EventType>().Invoke();
}
public static void Trigger<EventType, FirstParam>(FirstParam firstParam) where EventType : UnityEvent
{
GetEvent<EventType>().Invoke(firstParam);
}
}
其他脚本可以订阅/取消订阅事件并触发事件。现在出现了两个问题,它们在一起:
UnityEvent
存储到字典中,因为它只能容纳非通用字典最佳重载的Add方法'Dictionary.Add(Type, 集合初始值设定项的“ UnityEvent”)具有无效的参数 (CS1950)[Assembly-CSharp]参数2:无法从 从'LevelSceneLoadedGameEvent'到'UnityEngine.Events.UnityEvent' (CS1503)[Assembly-CSharp]
Trigger
方法在Invoke
失败,因为GetEvent
返回了一个非通用的UnityEvent
方法'Invoke'的重载不接受1个参数(CS1501) [Assembly-CSharp]
如何修复我的 EventManager 以处理非通用和通用UnityEvents
?
答案 0 :(得分:3)
UnityEvent有几个泛型重载,可用于添加参数(例如字符串,整数等)
基本上,Unity会序列化的任何数据类型都会显示在检查器中。
因此,如果您希望使用字符串引发事件,则基本上需要使用UnityEvent<string>
。
Here是使用单个参数UnityEvent的示例。
答案 1 :(得分:0)
我通过将从字典获得的UnityEvent强制转换为所需的通用类型来修复它,并在向字典添加事件时将其强制强制转换为UnityEvent。另外,我必须对字典使用UnityEventBase
,因为它是事件的基类。
固定代码:
public static class GameEventManager
{
private static Dictionary<Type, UnityEventBase> events = new Dictionary<Type, UnityEventBase>()
{
{
typeof(LevelSceneLoadedGameEvent),
new LevelSceneLoadedGameEvent()
}
};
private static EventType GetEvent<EventType>() where EventType : UnityEventBase
{
UnityEventBase unityEvent = events[typeof(EventType)];
return (EventType)unityEvent;
}
public static void SubscribeTo<EventType>(UnityAction listener) where EventType : UnityEvent
{
GetEvent<EventType>().AddListener(listener);
}
public static void UnsubscribeFrom<EventType>(UnityAction listener) where EventType : UnityEvent
{
GetEvent<EventType>().RemoveListener(listener);
}
public static void SubscribeTo<EventType, FirstParam>(UnityAction<FirstParam> listener) where EventType : UnityEvent<FirstParam>
{
GetEvent<EventType>().AddListener(listener);
}
public static void UnsubscribeFrom<EventType, FirstParam>(UnityAction<FirstParam> listener) where EventType : UnityEvent<FirstParam>
{
GetEvent<EventType>().RemoveListener(listener);
}
public static void Trigger<EventType>() where EventType : UnityEvent
{
GetEvent<EventType>().Invoke();
}
public static void Trigger<EventType, FirstParam>(FirstParam firstParam) where EventType : UnityEvent<FirstParam>
{
GetEvent<EventType>().Invoke(firstParam);
}
}