我在Unity3D中实现了Effects的类(具有在FixedUpdate循环中应用行为的持续时间的东西)。
我有一个基本抽象效果类,它具有跟踪持续时间的行为,在持续时间结束时删除自身,并在持续时间结束时调用受保护的抽象_doEffect函数。在我的派生类中,我重写_doEffect来创建具有不同行为的效果。
public abstract class Effect : MonoBehaviour
{
public virtual float kDuration { get { return 1.0f; }}
public static bool IsStackable { get { return false; }}
private float _elapsed = 0.0f;
protected virtual void Start()
{
_elapsed = kDuration;
}
protected virtual void FixedUpdate()
{
_elapsed -= Time.fixedDeltaTime;
if(_elapsed <= 0) {
Destroy(this);
}
_doEffect();
}
protected abstract void _doEffect();
}
现在,因为你不能在Unity3D中使用构造函数,所以当我将这种类型的新效果应用于游戏对象时,我需要为每个派生的Effect类执行以下操作:
1)如果此类效果不可堆叠,则从游戏对象中删除此monobehaviour的所有其他实例。 2)为游戏对象创建效果类型的新组件。 3)做一些特定于该效果类型的初始化。
对于这些要求,我想象做像
这样的事情public class DerivedEffect : Effect
{
public override float kDuration { get {return 1.0f; }}
public static bool IsStackable { get { return true; }}
private int _derivedData;
public static void Create(GameObject obj, int data)
{
DerivedEffect effect = DerivedEffect.CreateEffect(obj);
effect._data = data;
}
protected override void _doEffect()
{
//Do some stuff
}
}
然后在基类中放置
public static virtual Effect CreateEffect(GameObject obj)
{
//T is somehow magically the type of the class you called this function on
if(!T.IsStackable()) {
//delete all components of type T on obj
}
T effect = obj.AddComponent<T>();
return effect;
}
显然,这是不可能的,除非我做一些奇怪的东西与泛型和反射似乎有点极端,可能不是正确的做事方式。
关键是我需要一个静态函数,它执行1),2),3),我想分享执行1)和2)的代码,1)取决于每个不同的bool衍生类。
对于这些需求,什么是正确的,有效的设计?
答案 0 :(得分:0)
对于这些需求,什么是正确的,有效的设计?
Unity是基于组件的,当你想像普通的C#应用程序一样使用它时会让事情变得复杂。
最简单的方法是使用Composition。将Effect
类设为自己的非抽象类。只是一个继承自MonoBehaviour
的普通类。您可以使用AddComponent
轻松创建新的实例,并使用GetComponent
获取该实例。这个脚本也可以在计时器完成计数后直接销毁自己,没有任何问题。
在DerivedEffect
类中创建一个全局变量来保存创建的Effect
脚本的实例,这个脚本可以一遍又一遍地重复使用,直到它变为null,这意味着脚本被毁了。请注意,此处不涉及继承,DerivedEffect
脚本仅用作管理Effect
脚本的脚本示例。