You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中敌人攻击玩家无法触发takeDamage造成伤害问题求助

问题:敌人攻击无法对玩家施加伤害

我编写了一个脚本用于检测玩家是否在附近,触发敌人攻击动画并对玩家造成伤害,但目前遇到伤害无法生效的问题:已在攻击命中帧设置动画事件,调用玩家脚本中的takeDamage方法减少生命值,但玩家生命值无任何变化。

敌人AI脚本代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyAI : MonoBehaviour
{
    [SerializeField] private float attackCooldown;
    [SerializeField] private int damage;
    private float cooldownTimer = Mathf.Infinity;
    [SerializeField] private BoxCollider2D boxCollider;
    [SerializeField] private LayerMask playerLayer;
    [SerializeField] private float range;
    [SerializeField] private float ColliderDistance;
    private Animator anim;
    public PlayerHealth playerHealth;

    private void Awake()
    {
        anim = GetComponent<Animator>();
    }


    private void Update()
    {
        cooldownTimer += Time.deltaTime;

        if (playerInSight())
        {
            if (cooldownTimer >= attackCooldown)
            {
                cooldownTimer = 0;
                anim.SetTrigger("meleeAttack");

            }
        }
    }

    private bool playerInSight()
    {
        RaycastHit2D hit = 
        Physics2D.BoxCast(boxCollider.bounds.center + transform.right * range * transform.localScale.x * ColliderDistance,
        new Vector3(boxCollider.bounds.size.x * range, boxCollider.bounds.size.y, boxCollider.bounds.size.z)
        , 0, Vector2.left, 0, playerLayer);

        return hit.collider != null;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireCube(boxCollider.bounds.center + transform.right * range * transform.localScale.x * ColliderDistance,
         new Vector3(boxCollider.bounds.size.x * range, boxCollider.bounds.size.y, boxCollider.bounds.size.z));
    }

    private void damagePlayer()
    {
        if (playerInSight())
        {
            playerHealth.takeDamage(damage);
        }
    }
}

玩家受伤害方法代码

public void takeDamage(int damage)
{
    currentHealth -= damage;

    if (currentHealth < maxHealth && !_isPlayingAnimation)
    {
        maxHealth = currentHealth;
        anim.SetTrigger("attacked");
        _isPlayingAnimation = true;
    }

    if (currentHealth <= 0)
    {
        Debug.Log("Player has died!");
        anim.SetBool("isDead", true);
        _isPlayingAnimation = true;
    }
}

排查方向

  • 检查PlayerHealth引用:EnemyAI中的playerHealth字段需在Unity编辑器中手动拖入挂载了PlayerHealth组件的玩家对象,未赋值会导致空引用,无法调用takeDamage。可在damagePlayer中添加Debug.Log(playerHealth)验证是否为空。
  • 验证动画事件绑定:确认攻击动画的命中帧上,动画事件的函数名是damagePlayer(大小写一致、无拼写错误),且绑定的对象是敌人的EnemyAI组件。
  • 攻击帧时玩家是否在检测范围内:动画播放过程中敌人位置可能偏移,导致damagePlayer内的playerInSight()返回false。可暂时注释掉该if判断,直接调用playerHealth.takeDamage(damage)测试是否生效。
  • 修正玩家脚本逻辑错误:玩家takeDamage中maxHealth = currentHealth是错误逻辑——maxHealth应代表玩家最大生命值,不应随当前生命值降低而修改,这会导致后续生命值判断异常,甚至视觉上看起来没掉血。需删除该行代码。
  • 检查LayerMask设置:确认EnemyAI的playerLayer已正确选择玩家所在的Layer,否则playerInSight会一直返回false,无法触发攻击和伤害逻辑。

内容的提问来源于stack exchange,提问作者0-0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:46:16