Unity 2D攻击系统仅在移动时生效问题求助
Unity攻击系统静止时无法触发伤害的问题排查
近期开始用Unity开发游戏,实现了攻击系统脚本AttackDamage和生命值系统脚本Health。移动状态下攻击能正常造成伤害,但静止时攻击区域虽显示,却无法触发伤害判定。代码来自可正常运行的在线资源,除Health脚本外与原代码一致,找不到问题原因,求解决。
攻击系统脚本(AttackDamage)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AttackDamage : MonoBehaviour { private float attackDamage = 20; private void OnTriggerEnter2D(Collider2D other) { if (other.GetComponent<Health>() != null) { Health health = other.GetComponent<Health>(); health.TakeDamage(attackDamage); } } }
生命值系统脚本(Health)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class Health : MonoBehaviour { public Image healthBar; public float healthAmount = 100; private void Update() { if (healthAmount <= 0) { SceneManager.LoadScene(0); } } public void TakeDamage(float Damage) { healthAmount -= Damage; healthBar.fillAmount = healthAmount / 100; } public void Healing(float healPoints) { healthAmount += healPoints; healthAmount = Mathf.Clamp(healthAmount, 0, 100); healthBar.fillAmount = healthAmount / 100; } }
附问题演示视频:展示了移动时攻击正常扣血、静止时攻击区域重叠但无伤害判定的现象。
问题原因与解决方案
核心问题:OnTriggerEnter2D仅在两个碰撞体首次重叠的瞬间触发。静止时如果攻击区域和目标已经处于重叠状态,不会调用该方法。
方案1:改用OnTriggerStay2D并添加冷却
替换触发器检测方法,每帧检测重叠状态,同时加冷却避免重复扣血:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AttackDamage : MonoBehaviour { private float attackDamage = 20; private float attackCooldown = 0.5f; // 可根据需求调整 private bool canAttack = true; private void OnTriggerStay2D(Collider2D other) { if (canAttack && other.GetComponent<Health>() != null) { canAttack = false; other.GetComponent<Health>().TakeDamage(attackDamage); Invoke(nameof(ResetAttack), attackCooldown); } } private void ResetAttack() { canAttack = true; } }
方案2:主动检测攻击范围内的目标(推荐)
脱离触发器依赖,在攻击动画的关键帧调用检测方法,精准控制伤害时机:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AttackDamage : MonoBehaviour { private float attackDamage = 20; public LayerMask enemyLayer; // 在Inspector中选择敌人所在层 public float attackRange = 0.5f; // 根据攻击区域大小调整 // 将此方法绑定到攻击动画的伤害触发帧(动画窗口中添加事件) public void PerformAttack() { // 检测范围内的敌人 Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(transform.position, attackRange, enemyLayer); foreach (Collider2D enemy in hitEnemies) { Health health = enemy.GetComponent<Health>(); if (health != null) { health.TakeDamage(attackDamage); } } } }
基础检查项
- 确保攻击区域的
Collider2D已勾选Is Trigger - 目标物体的
Collider2D未勾选Is Trigger(若为静态物体,需添加Rigidbody2D并设为静态) - 两者的
Layer设置正确,未在Physics2D设置中取消层间碰撞
内容的提问来源于stack exchange,提问作者Sebastian Migliarelli
相关产品推荐
相关产品推荐

