Unity多树木砍伐功能异常:多树触发时攻击无法持续
问题分析与解决方案
你的核心问题出在两处逻辑漏洞:
- 只要有任意一棵树离开Trigger,就直接触发停止攻击的动画,完全忽略了列表里还有其他存活树木的情况
- 没有处理树木生命值归零时从攻击列表移除的逻辑,也没在此时判断是否需要停止攻击
修复后的代码实现
[SerializeField] PlayerData playerData; [SerializeField] PlayerTileCollector collector; public List<Damageable> damageableList = new List<Damageable>(); private int attackLayerIndex; public float damageAmount = 0.1f; private void Awake() { attackLayerIndex = playerData.playerAnimator.GetLayerIndex("Attack"); } private void OnTriggerEnter(Collider other) { var tree = other.gameObject.GetComponent<Damageable>(); if (!tree || tree.tag != "Tree") return; // 避免重复添加同一棵树到列表 if (!damageableList.Contains(tree)) { damageableList.Add(tree); } // 仅当攻击列表从空变为有树木时才触发攻击动画,防止重复触发导致的动画混乱 if (damageableList.Count == 1) { playerData.axe.gameObject.SetActive(true); playerData.playerAnimator.SetLayerWeight(attackLayerIndex, 1f); playerData.playerAnimator.SetTrigger("Attack"); } } private void OnTriggerExit(Collider other) { var tree = other.gameObject.GetComponent<Damageable>(); if (!tree || tree.tag != "Tree") return; damageableList.Remove(tree); // 只有当所有树木都离开/死亡,列表为空时才停止攻击 if (damageableList.Count == 0) { playerData.axe.gameObject.SetActive(false); playerData.playerAnimator.SetTrigger("Stop"); } } public void PlayerAttack() { // 用临时列表遍历,避免遍历原列表时移除元素引发异常 var treesToAttack = new List<Damageable>(damageableList); foreach (var tree in treesToAttack) { tree.TreeTakeDamage(damageAmount, collector); // 假设你的Damageable类有IsDead属性用于判断树木是否死亡 if (tree.IsDead) { damageableList.Remove(tree); } } // 攻击结束后检查是否还有存活树木,没有则自动停止攻击 if (damageableList.Count == 0) { playerData.axe.gameObject.SetActive(false); playerData.playerAnimator.SetTrigger("Stop"); } }
关键修改说明
- OnTriggerEnter优化:增加重复添加检查,并且只在攻击列表从空转为非空时触发动画,避免多次触发动画导致的逻辑混乱
- OnTriggerExit修复:不再单棵树离开就停止攻击,而是检查列表是否为空,确保还有树木时攻击持续
- PlayerAttack逻辑补充:
- 使用临时列表遍历,规避遍历原列表时修改元素引发的异常
- 攻击后主动检查树木是否死亡,死亡则从列表移除
- 攻击结束后再次校验列表状态,确保所有树木死亡后自动停止攻击
内容的提问来源于stack exchange,提问作者MahsaMohseni
相关产品推荐
相关产品推荐

