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

Unity敌人受击血量/动画异常问题排查求助

问题描述

编写了EnemyHealth脚本,期望实现敌人受击时播放动画并减少血量,但遇到异常:

  • 原条件if (currentHealth < maxHealth&& !_isPlayingAnimation)下,受击时动画正常播放但血量不减少;
  • 将条件改为if (currentHealth > maxHealth&& !_isPlayingAnimation)后,血量正常减少但动画完全不播放。

附上完整代码:

EnemyHealth脚本

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

public class EnemyHealth : MonoBehaviour
{
    public float maxHealth;
    public float currentHealth;
    private Animator anim;
    private bool _isPlayingAnimation;
    private Animation animation;

    void Start()
    {
        anim = GetComponent<Animator>();
        animation = GetComponent<Animation>();
        maxHealth = 100;
        currentHealth = 100;
    }

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

        if (currentHealth <= 0)
            Debug.Log("Enemy is dead");
    }

    public void animationPlayIsFalse()
    {
        _isPlayingAnimation = false;
    }
}

玩家攻击代码

enemyGameObject.GetComponent<EnemyHealth>().currentHealth -= damage;
问题分析
  1. 原条件下血量不减少的原因:Update方法里的currentHealth = maxHealth;语句会在检测到血量低于最大值时,立刻把血量重置回满值。玩家攻击减少的血量被这行代码直接覆盖,所以看起来血量没变化。
  2. 修改条件后动画不播放的原因:玩家攻击是减少敌人血量,currentHealth只会小于或等于maxHealth,currentHealth > maxHealth的条件永远不会成立,自然不会触发动画。
  3. 核心逻辑错误:靠Update轮询血量变化来触发动画的设计不合理,应该在敌人受到攻击时直接触发动画,而不是靠帧检测反向修正血量。
解决方法

修改EnemyHealth脚本

封装受伤处理方法,直接在受伤时处理血量减少和动画触发,移除Update里的错误重置逻辑:

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

public class EnemyHealth : MonoBehaviour
{
    public float maxHealth;
    public float currentHealth;
    private Animator anim;
    private bool _isPlayingAnimation;

    void Start()
    {
        anim = GetComponent<Animator>();
        maxHealth = 100;
        currentHealth = 100;
        // 移除无用的Animation组件引用
    }

    void Update()
    {
        if (currentHealth <= 0)
            Debug.Log("Enemy is dead");
    }

    // 封装受伤方法,外部调用这个方法来让敌人掉血
    public void TakeDamage(float damage)
    {
        if (_isPlayingAnimation || currentHealth <= 0)
            return; // 动画播放中或已死亡时不处理

        currentHealth -= damage;
        currentHealth = Mathf.Max(currentHealth, 0); // 防止血量低于0
        anim.SetTrigger("attacked");
        _isPlayingAnimation = true;
    }

    public void animationPlayIsFalse()
    {
        _isPlayingAnimation = false;
    }
}

修改玩家攻击代码

不再直接修改currentHealth字段,而是调用封装好的TakeDamage方法:

enemyGameObject.GetComponent<EnemyHealth>().TakeDamage(damage);

额外注意

确保敌人Animator组件中的attacked触发器已正确设置,并且动画片段的动画事件已添加,在动画结束时调用animationPlayIsFalse方法,重置播放状态。


内容的提问来源于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.13 08:35:18