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
相关产品推荐
相关产品推荐

