C# 我如何制作某些无需事件即可订阅的函数(如Unity)?
在Unity中,当您创建一个新的C# 我如何制作某些无需事件即可订阅的函数(如Unity)?,c#,inheritance,unity3d,abstract-class,C#,Inheritance,Unity3d,Abstract Class,在Unity中,当您创建一个新的monobhavior类时,它附带了一整套可以轻松挂接的函数,例如Update()、FixedUpdate()和Awake()。我正在创建自己的组件实体系统,并且我正在尝试添加一系列功能,这些功能可以很容易地由我创建的组件连接。我将基类抽象化,并将Update和Draw作为抽象函数,然后可以继承它们。这很好,除了我的所有组件都必须实现所有这些功能之外;像初始化这样的东西对某些组件很有用,但对其他组件则没有,我不知道如何模拟这种行为 它是通过反射完成的吗?您可以将方
monobhavior
类时,它附带了一整套可以轻松挂接的函数,例如Update()
、FixedUpdate()
和Awake()
。我正在创建自己的组件实体系统,并且我正在尝试添加一系列功能,这些功能可以很容易地由我创建的组件连接。我将基类抽象化,并将Update
和Draw
作为抽象函数,然后可以继承它们。这很好,除了我的所有组件都必须实现所有这些功能之外;像初始化这样的东西对某些组件很有用,但对其他组件则没有,我不知道如何模拟这种行为
它是通过反射完成的吗?您可以将方法定义为虚拟方法,而不是将其定义为抽象方法,并仅在必要时重写它们
class BaseComponent : MonoBehaviour
{
public virtual void OnAwesomeEvent()
{
// do nothing or implement default behaviour
}
}
class ShinyComponent : BaseComponent
{
public override void OnAwesomeEvent()
{
Debug.Log("I've been waiting for this!");
// If you need the default implementation you can call it with
// base.OnAwesomeEvent()
}
}
class LazyComponent : BaseComponent
{
// I do nothing and no one cares
}
您可以将方法定义为虚拟方法,而不是将其定义为抽象方法,并仅在必要时重写它们
class BaseComponent : MonoBehaviour
{
public virtual void OnAwesomeEvent()
{
// do nothing or implement default behaviour
}
}
class ShinyComponent : BaseComponent
{
public override void OnAwesomeEvent()
{
Debug.Log("I've been waiting for this!");
// If you need the default implementation you can call it with
// base.OnAwesomeEvent()
}
}
class LazyComponent : BaseComponent
{
// I do nothing and no one cares
}
免责声明:
我正在创建自己的组件实体系统,并尝试添加一个
可由组件I轻松连接的功能范围
创造
我并不特别喜欢unity在这方面的“神奇方法”。我认为实现接口
或覆盖虚拟函数
通常是一个更干净的解决方案。
我曾经使用过Unity的方法,对于一个AI插件,它应该调用用户定义的方法,而不必强制扩展类(基本上是因为我必须避免在修改AI行为时重新编译代码)
在任何情况下,对于与实施有关的内容:
1)发送消息
使用纯反射实现:只有在调用SendMessage
时才能知道目标方法名称。
这似乎很方便(也许是这样,我仍然没有使用过,也觉得有必要使用),但有几个缺点:
唤醒
,更新
,碰撞
,…)略有不同,因为Unity可以知道签名并编译代理。(我不确定实现情况,但我做过类似的事情)
本文很好地描述了实现类似功能的方法。
基本上,您只在初始化中使用反射,但一旦获得MethodInfo
,就可以使用delegate.CreateDelegate
将方法编译为委托
结果:
- 您仍然使用反射,但仅在初始化中使用
- 一旦编译,委托几乎与标准方法调用(或事件)一样快
接口
或覆盖虚拟函数
通常是一个更干净的解决方案。
我曾经使用过Unity的方法,对于一个AI插件,它应该调用用户定义的方法,而不必强制扩展类(基本上是因为我必须避免在修改AI行为时重新编译代码)
在任何情况下,对于与实施有关的内容:
1)发送消息
使用纯反射实现:只有在调用SendMessage
时才能知道目标方法名称。
这似乎很方便(也许是这样,我仍然没有使用过,也觉得有必要使用),但有几个缺点:
唤醒
,更新
,碰撞
,…)略有不同,因为Unity可以知道签名并编译代理。(我不确定实现情况,但我做过类似的事情)
本文很好地描述了实现类似功能的方法。
基本上,您只在初始化中使用反射,但一旦获得MethodInfo
,就可以使用delegate.CreateDelegate
将方法编译为委托
结果:
- 您仍然使用反射,但仅在初始化中使用
- 一旦编译,委托几乎与标准方法调用(或事件)一样快