Unity游戏攻击触发异常:史莱姆受击动画生效但击退失效
问题:碰撞击退失效,攻击触发检测异常
攻击史莱姆时,触发检测未正常激活,击退功能完全失效,仅受击动画正常运行。
史莱姆(Slime)代码
Animator animator; Rigidbody2D rb; public float knockbackDamping = 0.5f; public float health = 3; public float Health { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } void Start() { animator = GetComponent<Animator>(); rb = GetComponent<Rigidbody2D>(); } public void TakeDamge(float damage) { throw new System.NotImplementedException(); health -= damage; if (health <= 0) { animator.SetTrigger("death"); } if (damage >= 0) { animator.SetTrigger("hit"); } } public void OnHit(float damage, Vector2 knockback) { health -= damage; rb.AddForce(new Vector3(knockback.x, knockback.y, 0f)); // 补充受击动画触发 animator.SetTrigger("hit"); if (health <= 0) { animator.SetTrigger("death"); } } public void Defeated() { Destroy(gameObject); } void OnTriggerEnter2D(Collider2D coll) { if (coll.tag == "sword") { OnHit(1, Vector2.zero); Debug.Log("Slime получил урон!"); } } public void TakeDamage(float damage) { throw new System.NotImplementedException(); } void Update() { rb.velocity *= knockbackDamping; }
剑(Sword)代码
Vector2 movementInput; public Collider2D swordcollider; public float swordDamage = 1f; public float knockbackForce = 30f; Vector2 rightAttackOffset; public Vector3 faceright = new Vector3(0.1f, -0.1f, 0); public Vector3 faceleft = new Vector3(-0.5f, -0.1f, 0); void Start() { swordcollider = GetComponent<Collider2D>(); rightAttackOffset = transform.localPosition; // 改为localPosition避免父物体移动影响 if (swordcollider == null) { Debug.LogWarning("Sword collider not set"); } // 默认禁用碰撞器,避免持续触发 swordcollider.enabled = false; } public void AttackRight() { print("AttackR"); swordcollider.enabled = true; transform.localPosition = rightAttackOffset; // 攻击后延迟关闭碰撞器,避免重复触发 Invoke(nameof(DisableSwordCollider), 0.2f); } public void AttackLeft() { print("AttackL"); swordcollider.enabled = true; transform.localPosition = new Vector3(rightAttackOffset.x * -1, rightAttackOffset.y); Invoke(nameof(DisableSwordCollider), 0.2f); } private void DisableSwordCollider() { swordcollider.enabled = false; } private void SetSwordOffset(bool isFacingRight) { if (isFacingRight) { swordcollider.transform.localPosition = faceright; } else { swordcollider.transform.localPosition = faceleft; } } public void IsFacingRight(bool isFacingRight) { SetSwordOffset(isFacingRight); } public float damage = 10; private void OnTriggerEnter2D(Collider2D other) { IDamagable damagable = other.GetComponent<IDamagable>(); if (damagable != null) { Vector3 parentPosition = transform.parent.position; Vector2 direction = (other.transform.position - parentPosition).normalized; Vector2 knockback = direction * knockbackForce; damagable.OnHit(swordDamage, knockback); } else { Debug.LogWarning("Collider cant"); } }
IDamagable接口代码
public interface IDamagable { float Health { get; set; } void OnHit(float damage, Vector2 knockback); void TakeDamage(float damage); }
核心修复点
- 接口语法修复:IDamagable接口缺少大括号,补上后才能正常实现接口,解决编译错误。
- 史莱姆类接口实现优化:
- 移除
TakeDamage和TakeDamge方法中的throw new NotImplementedException(),避免调用时直接崩溃;可将逻辑合并到OnHit中统一处理。 - 在
OnHit中补充受击动画、死亡动画的触发逻辑,确保状态正确更新。
- 移除
- 剑的碰撞器管理:
- 默认禁用剑的碰撞器,攻击时启用,攻击结束后通过
Invoke延迟关闭,避免持续触发碰撞检测。 - 将
rightAttackOffset改为transform.localPosition,避免父物体移动导致攻击位置偏移。
- 默认禁用剑的碰撞器,攻击时启用,攻击结束后通过
- 击退效果优化:
- 史莱姆
Update中的rb.velocity *= knockbackDamping会持续削弱速度,可调整阻尼值(如设为0.9f),或仅在非击退状态下应用阻尼,避免击退力被直接抵消。 - 在
OnHit的AddForce中指定力模式为ForceMode2D.Impulse,让击退效果更明显:rb.AddForce(knockback, ForceMode2D.Impulse);
- 史莱姆
- 触发逻辑冲突处理:史莱姆和剑的
OnTriggerEnter2D会重复触发OnHit,建议保留剑的接口调用逻辑(更灵活),移除史莱姆中的标签检测代码,避免重复扣血和逻辑冲突。
内容的提问来源于stack exchange,提问作者Rigel
相关产品推荐
相关产品推荐

