在C#

时间:2017-06-28 10:12:52

标签: c# oop inheritance unity3d design-patterns

我在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衍生类。

对于这些需求,什么是正确的,有效的设计?

1 个答案:

答案 0 :(得分:0)

  

对于这些需求,什么是正确的,有效的设计?

Unity是基于组件的,当你想像普通的C#应用​​程序一样使用它时会让事情变得复杂。

最简单的方法是使用Composition。将Effect类设为自己的非抽象类。只是一个继承自MonoBehaviour的普通类。您可以使用AddComponent轻松创建新的实例,并使用GetComponent获取该实例。这个脚本也可以在计时器完成计数后直接销毁自己,没有任何问题。

DerivedEffect类中创建一个全局变量来保存创建的Effect脚本的实例,这个脚本可以一遍又一遍地重复使用,直到它变为null,这意味着脚本被毁了。请注意,此处不涉及继承,DerivedEffect脚本仅用作管理Effect脚本的脚本示例。