c# - 如何统一实现事件发送者 - 事件接收者游戏对象?
问题描述
我有“A”类,它将发送事件“a”。订阅事件“a”的类将对此事件作出反应。其他类可以订阅事件“a”,而无需更改“A”类中的任何内容;
现在,团结起来最合理的方法是什么?是否有一些消息传递系统已经可以做到这一点?
如果不是,我是否应该制作类似 EventManager 类的东西,它将订阅者类存储在数组中并调用它们的方法?
解决方案
可能有很多方法可以做到这一点。
公共静态列表
public class A : MonoBehaviour
{
public static List<A> AvailableAs = new List<A>();
private void Awake()
{
if(!AvailableAs.Contains(this)) AvailableAs.Add(this);
}
private void OnDestroy()
{
if(AvailableAs.Contains(this)) AvailableAs.Remove(this);
}
public void SomePublicMethod()
{
// magic
}
}
并使用它,例如
public class B : MonoBehaviour
{
// run the method on all currently registered A instances
public void DoIt()
{
foreach(var a in A.AvailableAs)
{
a.SomePublicMethod();
}
}
}
全局事件处理程序
或者,如果您更愿意进行封装,就像您提到的所有 A 一样的全局事件处理程序
namespace ANamespace
{
public static class AEventHandler
{
internal static event Action OnInvokeA;
public static void InvokeAEvent()
{
if(OnInvokeA != null) OnInvokeA.Invoke();
}
}
}
并且在 A 中有
namespace ANamespace
{
public class A : MonoBehaviour {
private void Awake()
{
// it is save to remove a callback first even
// if it was not added yet. This makes sure it is
// added only once always
AEventHandler.OnIvokeA -= SomePrivateMethod;
AEventHandler.OnIvokeA += SomePrivateMethod;
}
private void OnDestroy()
{
AEventHandler.OnIvokeA -= SomePrivateMethod;
}
private void SomePrivateMethod()
{
// magic
}
}
}
现在在B
你宁愿简单地做
// invoke the event and whoever is added as listener will do
// whatever he registered
// in this case all A instances execute their method
AEventHandler.InvokeAEvent();
团结事件
但是,如果您只有一个引发事件的类A
并且您希望其他人对其做出反应,只需使用UnityEvent
类似
public class A : MonoBehaviour
{
public UnityEvent OnSomethingHappened = new UnityEvent();
private void SomeMethodIWillRun()
{
//...
OnSomethingHappened.Invoke();
}
}
现在,您可以通过拖入 GameObjects/Components 并选择要调用的方法轻松地在 Unity Inspector 中为该事件添加回调。onClick
(顺便说一句,组件的事件使用完全相同的东西Button
。;))
你仍然可以在运行时通过脚本添加回调,比如
public class B : MonoBehaviour
{
public A referenceToA;
private void Start()
{
referenceToA.OnSomethingHappened.AddCallback(OnASomethingHappened);
}
private void OnDestroy()
{
referenceToA.OnSomethingHappened.RemoveCallback(OnASomethingHappened)
}
private void OnASomethingHappened()
{
//
}
}
注意:在智能手机上打字,所以没有保修,但我希望这个想法很清楚。
推荐阅读
- javascript - 以 4 的倍数返回值
- node.js - 如何使用 ExpressJS 在我的应用程序中正确记录错误
- ruby-on-rails - 无法加载此类文件--restclient/instrumentation
- detox - 排毒:每次测试前需要调用 device.reloadReactNative 吗?
- javascript - 在 useEffect 中反应 setState 第一次调用不会起作用
- entity-framework - EF 核心请求中的线程
- python - 在 HTML 中显示不断变化的 Python 变量
- bison - 在 Windows 上运行野牛时出错“冲突:1 shift/reduce,1 reduce/reduce C:\GnuWin32\bin\bison.exe: m4: Invalid argument”
- php - 计算PHP laravel中数字的百分比
- c++ - 线程 - 如何访问 lambda 函数内的成员变量?