-1

我最近开始学习 c#,但遇到了一个错误,希望你们中的一些人能够帮助我。我们正在 Unity5 中开发一款游戏,当玩家的生命值为 0 时,布娃娃功能将启动,但不幸的是我不能称之为死亡,因为它是一个方法组......有什么想法吗?干杯。这是代码(我将其注释掉,因此我可以在 Unity 中进入播放模式,因为错误不允许我进入第 47 行和第 53 行):

using UnityEngine;
using System.Collections;

public class EnemyAI_Basic : MonoBehaviour
{
    private EnemyAI_Basic enemyAI_Basic;
    Animator controller;
    float health;
    Animator anim;
    bool Alive = true;
    public bool Dead = false;
    int pointValue = 5;
    private Collider myCollider;
    private Rigidbody myRigidbody;

    CapsuleCollider capsuleCollider;


    void Start()
    {
        controller = GetComponentInParent<Animator>();
        health = 40;
        capsuleCollider = GetComponent<CapsuleCollider>();
        anim = GetComponent<Animator>();
    }

    void Update()
    {
        if (!Dead)
        {
            anim.SetTrigger("Alive");
        }
    }

    void Death()
    {
        Dead = true;
        Alive = false;
        capsuleCollider.isTrigger = true;
        anim.SetTrigger("Dead");
        Destroy(gameObject, 4f);
    }

    void OnEnable()
    {
        SetInitialReferences();
        enemyAI_Basic.Death += ActivateRagdoll;
    }


    void OnDisable()
    {
        enemyAI_Basic.Death -= ActivateRagdoll;
    }

    void SetInitialReferences()
    {
        enemyAI_Basic = transform.root.GetComponent<EnemyAI_Basic>();

        if (GetComponent<Collider>() != null)
        {
            myCollider = GetComponent<Collider>();
        }

        if (GetComponent<Rigidbody>() != null)
        {
            myRigidbody = GetComponent<Rigidbody>();
        }

    }

    void ActivateRagdoll()
    {
        if (myRigidbody != null)
        {
            myRigidbody.isKinematic = false;
            myRigidbody.useGravity = true;
        }

        if (myCollider != null)
        {
            myCollider.isTrigger = false;
            myCollider.enabled = true;
        }
    }
}
4

1 回答 1

1

我看到了你的问题。在这种情况下,您将死亡方法视为委托,但事实并非如此。您只能将方法注册到委托或事件,不能将方法注册到方法组。对于您的情况,有几种方法可以解决此问题。

第一个解决方案,也是迄今为止最简单的解决方案,在 Death 函数中调用 ActivateRagdoll,如下所示:

void Death()
{
    Dead = true;
    Alive = false;
    capsuleCollider.isTrigger = true;
    anim.SetTrigger("Dead");
    ActivateRagdoll();
    Destroy(gameObject, 4f);
}

然后删除:

enemyAI_Basic.Death += ActivateRagdoll;

enemyAI_Basic.Death -= ActivateRagdoll;

从 OnEnable 和 OnDisable 方法中,应该删除任何编译器错误。现在,为了使用这个方法,你所要做的就是从代码中的某个地方调用它。根据您杀死 Ai 的方式,您可能会考虑将该方法公开,或者在更新循环中包含一些死亡逻辑,

if(health <= 0)
{
   Death();
   enabled = false;  //disable the component so the update loop doesn't repeat the death procedure multiple times, Unity might not be pleased.
}

另一种方式,也是您尝试这样做的方式,是创建一个类可以订阅方法的事件。这个事件将调用所有订阅的方法,为它们提供一种被通知的方式,每当发生有趣的事情时,比如在这种情况下 Ai 死了。这对于不需要经常检查 Ai 死亡状态的外部类很有用,毕竟,如果 Ai 处于完全健康状态,他们可能不会关心它。他们只需要知道,艾何时死。事件是这种情况的理想选择。

要进行活动,您将执行以下操作:

public class EnemyAI_Basic : MonoBehaviour
{
    //your other variables

    public delegate void EnemyDies();  //declare the method types that can be registered to the event

    public event EnemyDies onEnemyDeath; //declare event, using the delegate for the method type

    //other methods here

    private void OnEnable()
    {
        //must be the same method type as the event, the compiler will let you know if it isn't
        onEnemyDeath += Death;
        onEnemyDeath += ActivateRagdoll;            
    }

    private void OnDisable()
    {
        onEnemyDeath -= Death;
        onEnemyDeath -= ActivateRagdoll;
    }

    //other things here

    //doesn't have to be public, just in case you want a bullet to kill the enemy
    public void KillAi()
    {
        //checking for null basically says: is anybody registered? If not, nothing to invoke. 
        //It will get upset if you try and invoke an event without any registered methods, hence the check.
        if(onEnemyDeath != null)
        {
            onEnemyDeath();
        }
    }

    void Death()
    {
       Dead = true;
       Alive = false;
       capsuleCollider.isTrigger = true;
       anim.SetTrigger("Dead");
       //ActivateRagdoll();   You don't have to manually call this now, invoking the event will call it for you.
       //Registration order is important, me thinks. Experiment :)
       Destroy(gameObject, 4f);
    }
}

还有其他几种方法可以构建这样的系统,但是,在您的情况下,这可能就是您所追求的。

一些阅读:

活动: https ://www.codeproject.com/Articles/11541/The-Simplest-C-Events-Example-Imaginable https://www.tutorialspoint.com/csharp/csharp_events.htm

代表:https ://msdn.microsoft.com/en-us/library/ms173171.aspx

方法组:什么是 C# 中的方法组?

希望这会有所帮助。

于 2017-03-11T21:52:48.260 回答