如何覆盖专门针对单元类型的组件功能?

时间:2019-02-03 19:38:26

标签: c# unity3d components

我有一个Health类,该类具有方法TakeDamage()和Die()。我的敌人类具有健康组件,因此当我的敌人受到伤害时,将执行Health.TakeDamage()。我该如何去覆盖Die()方法以对敌人的不同类型进行不同的工作。

1 个答案:

答案 0 :(得分:1)

创建一个基类

public abstract class Health : MonoBehaviour
{
    // make a member e.g. protected so it is not public but still accesible by inherited classes 
    protected float health = 100f;

    // Now you either can make the method abstract
    // This means every inheritor later HAS to implement this method
    public abstract void Die();

    // or you can make it virtual
    // This means this class already provides an implementation
    // but an inheritor could 
    //  a) simply use it
    //  b) extend it or 
    //  c) completely overrule it
    public virtual void TakeDamage()
    {
        Debug.Log("Ouch!");
        health -= 1;
    }
}

注意:如果您的Health类没有任何abstract方法,则您可能还希望从类定义本身中删除abstract关键字并使其仅public class Health : MonoBehaviour。但是,如果要严格防止基类Health本身被实例化,则可能需要保留它,以确保仅存在继承类型的组件。


现在您可以创建Health的不同实现,也可以完全不更改它

public class NormalHealth : Health
{
    // since it is abstract we have to implement Die
    public override void Die()
    {
        // whatever happens here
    }

    // But if we want to use the default TakeDamage we just do nothing
}

或覆盖默认行为

public class WeakHealth : Health
{
    // Since it is abstract we have to implement Die
    public override void Die()
    {
        // whatever happens here
    }

    // Now we replace the TakeDamage
    public override void TakeDamage()
    {
        // by not calling base.TakeDamage we don't execute the base implementation at all
        Debug.Log("Huge Ouch!");
        health -= 10;
    }
}

或扩展它而不是替换它

public class HealthWithSound : Health
{
    public AudioSource someAudioSource;
    public AudioClip someClip;

    // Since it is abstract we have to implement Die
    public override void Die()
    {
        // whatever happens here
    }

    // This time we only extend the base's TakeDamage with e.g. sound
    public override void TakeDamage()
    {
        base.TakeDamage();

        someAudioSource.PlayOneShot(someClip);
    }
}