如何实现多个Warrior实例同时攻击单个敌人并正确统计伤害?
如何实现多个Warrior实例同时攻击单个敌人并正确统计伤害?
兄弟,我看了你的代码,问题其实很明显——你把攻击冷却的逻辑放到了敌人脚本里,这就导致不管多少个Warrior过来攻击,只要有一个触发了伤害,敌人就会进入冷却状态,其他Warrior的攻击都被挡住了。
咱们来拆解下问题:你的OnCollisionStay2D里用了敌人自己的_TimeSinceLastAttack和冷却判断,相当于给敌人加了一个“全局冷却”,所有攻击者共享这个冷却,自然没办法同时触发多个伤害。
解决方案:把攻击逻辑移到Warrior那边去!
每个Warrior应该自己管理攻击间隔,而不是让敌人来控制。敌人只需要专注一件事:接收伤害并更新血量。这样多个Warrior就能各自独立攻击,互不干扰。
第一步:给Warrior写专属的攻击脚本
新建一个WarriorAttackScript挂在每个Warrior对象上,让每个战士自己判断什么时候能攻击:
using UnityEngine; public class WarriorAttackScript : MonoBehaviour { [SerializeField] private int attackPower = 20; // 每个战士的攻击力 [SerializeField] private float attackCooldown = 5f; // 每个战士的攻击间隔 private float _timeSinceLastAttack = 0f; private void Update() { // 持续累加时间,用来判断是否到了下次攻击的时间 _timeSinceLastAttack += Time.deltaTime; } private void OnCollisionStay2D(Collision2D collision) { // 碰到敌人,且自己的冷却时间到了 if (collision.gameObject.CompareTag("Enemy") && _timeSinceLastAttack >= attackCooldown) { // 获取敌人的血量脚本 HealthSystemScript enemyHealth = collision.gameObject.GetComponent<HealthSystemScript>(); if (enemyHealth != null) { // 调用敌人的受伤方法 enemyHealth.TakeDamage(attackPower); Debug.Log($"{gameObject.name} 给敌人造成了 {attackPower} 点伤害!"); // 重置自己的冷却时间 _timeSinceLastAttack = 0f; } } } }
第二步:简化敌人的血量脚本
把敌人脚本里和攻击冷却相关的逻辑全部删掉,让它只负责血量管理:
using UnityEngine; using UnityEngine.UI; public class HealthSystemScript : MonoBehaviour { public int maxHealth = 100; public int currentHealth; public HealthBar HealthBar; private void Start() { currentHealth = maxHealth; HealthBar.SetMaxHealth(maxHealth); } void Update() { // 原代码里的HealthBar.MaxHealth(currentHealth)应该是笔误,改成SetHealth更新当前血量显示 HealthBar.SetHealth(currentHealth); // 测试用的F键销毁,保留也没关系 if (Input.GetKey(KeyCode.F)) { Destroy(gameObject); } } public void TakeDamage(int damage) { currentHealth -= damage; HealthBar.SetHealth(currentHealth); // 受伤后直接判断是否死亡,不用在Update里重复检测 if (currentHealth <= 0) { Destroy(gameObject); } } }
为什么这样改就解决问题了?
- 每个Warrior独立控制自己的攻击冷却,多个战士同时碰敌人时,各自到了冷却时间就会触发伤害,敌人会依次接收每个战士的攻击。
- 敌人的职责变得单一,只处理血量变化和血条更新,代码更清晰,也不容易出逻辑冲突。
- 完全不需要维护什么Warrior列表,每个战士自己会处理攻击逻辑,简单高效。
额外小建议
- 如果你担心多个战士同时触发碰撞导致短时间内多次伤害,可以给敌人加个短暂的无敌帧(比如受伤后0.1秒内不接收伤害),但一般情况下没必要,除非你的游戏有特殊需求。
- 记得给敌人对象打上
Enemy标签,不然Warrior的碰撞检测找不到目标哦!
备注:内容来源于stack exchange,提问作者Aru Alonless
相关产品推荐
相关产品推荐

