在Unity 3d中使用动画事件处理近战攻击的好方法是什么?

时间:2017-05-20 16:12:34

标签: c# animation unity3d unity5

好吧所以我正在努力工作,就像一个黑客并在Unity中削减一些游戏,我有一个敌人的对象,我想攻击玩家并使用碰撞器造成伤害。我已经向敌人的攻击动画添加了一个事件,该动画调用了应该造成伤害的函数OnTriggerEnter(Collider other),但每当我尝试它时,我都会收到错误说“对象引用没有设置为对象的实例”。有没有人对如何使这项工作有任何想法?

1 个答案:

答案 0 :(得分:1)

此代码段对您有所帮助非常有帮助。我在一个旧项目中完成了这项工作并且运作良好。

在这种情况下是右腿踢动画。

注意:未测试的代码段。 “健康”脚本来源不包括在内。

public class MeleeAttackController : MonoBehaviour
{
    public SphereCollider kickAttackSphere; // in this case the sphere collider must be child of the right foot
    public float meleeAttackDamage = 50;
    public AudioClip kickAttackClip;

    CapsuleCollider m_capsule;

    void Awake()
    {
        kickAttackSphere.isTrigger = true;

        m_capsule = GetComponent<CapsuleCollider>();
    }

    void Event_KickAttack_RightLeg() // invoked by the kick animation events (in case you have many kick animations)
    {
        if(CheckSphereAndApllyDamage(kickAttackSphere))
        {
            if (kickAttackClip)
            {
                AudioSource.PlayClipAtPoint(kickAttackClip, weaponAttackSphere.transform.position); // play the sound
            }
        }
    }

    /// <summary>
    /// Returns true if the sphere collider overlap any collider with a health script. If overlap any collider also apply a the meleeAttackDamage.
    /// </summary>
    bool CheckSphereAndApllyDamage(SphereCollider sphere)
    {
        // check if we hit some object with a health script added
        Collider[] colliders = Physics.OverlapSphere(sphere.transform.position, sphere.radius, Physics.AllLayers, QueryTriggerInteraction.Ignore);

        foreach (Collider collider in colliders)
        {
            if (collider == m_capsule) continue; // ignore myself

            Health health = collider.GetComponent<Health>();
            if (health)
            {
                // if the collider we overlap has a health, then apply the damage
                health.TakeDamage(meleeAttackDamage, transform);

                return true;
            }
        }

        return false;
    }
}