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

Unity开发游戏敌人一击秒杀3条命,如何添加攻击冷却延迟?

问题解决方案

问题根源

  • 现有敌人攻击逻辑没有做实际的冷却拦截:StartCoroutine(Cooldown())只是异步启动协程,不会阻塞Update里的后续攻击代码,只要玩家处于攻击范围内,每帧都会执行1次扣血,每秒触发数十次自然直接秒杀玩家。
  • 生命值系统的Update逻辑存在冗余,每帧重复检测生命值并尝试销毁已销毁的心形UI对象,属于无效代码。

修复代码

修改后的Enemy脚本

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

public class Enemy : MonoBehaviour
{
    public Transform attackPoint;
    public float attackrange = 0.5f;
    public LayerMask playerlayers;
    public float speed = 3f;
    public float attackCooldown = 3f; // 可在Inspector直接调整冷却时长
    private Transform target;
    private bool canAttack = true; // 攻击权限控制变量

    IEnumerator Cooldown()
    {
        canAttack = false;
        yield return new WaitForSeconds(attackCooldown);
        canAttack = true;
    }

    private void Update()
    {
        if (target != null)
        {
            float step = speed * Time.deltaTime;
            transform.position = Vector2.MoveTowards(transform.position, target.position, step);
            
            // 只有满足攻击权限时才执行攻击检测
            if (canAttack)
            {
                Collider2D[] hitplayers = Physics2D.OverlapCircleAll(attackPoint.position, attackrange, playerlayers);
                foreach (Collider2D player in hitplayers)
                {
                    player.GetComponent<HeartSystem>().TakeDamage(1);
                    StartCoroutine(Cooldown());
                }
            }
        }
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.tag == "Player")
        {
            target = other.transform;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.tag == "Player")
        {
            target = null;
        }
    }

    void OnDrawGizmosSelected()
    {
        if (attackPoint == null)
            return;

        Gizmos.DrawWireSphere(attackPoint.position, attackrange);
    }
}

优化后的HeartSystem脚本

把心形UI更新逻辑放到TakeDamage方法里执行,避免每帧重复检测,记得在Inspector面板给life变量初始赋值为3:

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

public class HeartSystem : MonoBehaviour
{
    public GameObject[] hearts;
    public int life;

    private void Start()
    {
        // 初始化生命值,也可以直接在Inspector面板设置
        life = 3;
        UpdateHeartUI();
    }

    public void TakeDamage(int d)
    {
        life -= d;
        UpdateHeartUI(); // 受伤后才更新UI
        
        if (life <= 0)
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
        }
    }

    void UpdateHeartUI()
    {
        // 遍历所有心,根据当前生命值切换显示状态
        for (int i = 0; i < hearts.Length; i++)
        {
            hearts[i].SetActive(i < life);
        }
    }
}

注意事项

  • 请在HeartSystem的Inspector面板把3个心形UI对象按顺序拖入hearts数组
  • 敌人的attackCooldown参数可以直接在Inspector调整,无需修改代码

内容的提问来源于stack exchange,提问作者Max Herczeg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:45:01