2D游戏生命值系统实现:如何仅在踩踏敌人时对其造成伤害
Unity 2D 踩敌仅敌方受伤害的修复方案
问题根因
你当前的问题核心有两个:
- 玩家和敌人挂载了完全相同的碰撞伤害脚本,碰撞触发时两个物体的
OnCollisionEnter2D会同时执行,双方都会调用对方的血量组件扣血,自然两边都掉血 - 法线判断逻辑存在缺陷:
ContactPoint2D.normal是指向当前挂载脚本的物体的方向,你之前的写法没有区分敌我逻辑,且水平碰撞只判断了x正方向的法线,所以只有单侧碰撞生效
实现方法
建议将敌我碰撞逻辑拆分,不要共用同一套脚本,分别处理伤害判定:
1. 敌人挂载的碰撞脚本逻辑
仅当玩家撞到敌人头顶时,触发敌人掉血:
private void OnCollisionEnter2D(Collision2D coll) { // 仅处理和玩家的碰撞 if (coll.gameObject.CompareTag("Player")) { Health enemyHealth = GetComponent<Health>(); foreach (ContactPoint2D point2D in coll.contacts) { // 法线y≥0.5f说明碰撞来自敌人上方,即玩家踩头 if (point2D.normal.y >= 0.5f) { enemyHealth.takeDamage(damage); // 可选:给玩家添加向上弹跳的力,增强手感 Rigidbody2D playerRb = coll.gameObject.GetComponent<Rigidbody2D>(); playerRb.velocity = new Vector2(playerRb.velocity.x, 6f); } } } }
2. 玩家挂载的碰撞脚本逻辑
仅当玩家侧面/下方撞到敌人时,才触发玩家掉血,踩头时玩家不受伤害:
private void OnCollisionEnter2D(Collision2D coll) { // 仅处理和敌人的碰撞 if (coll.gameObject.CompareTag("Enemy")) { Health playerHealth = GetComponent<Health>(); foreach (ContactPoint2D point2D in coll.contacts) { // 法线y<0.5且水平分量更大,说明是侧面/下方碰撞 if (point2D.normal.y < 0.5f && Mathf.Abs(point2D.normal.x) > Mathf.Abs(point2D.normal.y)) { playerHealth.takeDamage(damage); } } } }
可选优化方案
如果担心斜向碰撞法线判定不稳定,可以给敌人头顶单独加一个小的BoxCollider2D,勾选Is Trigger,专门用来检测玩家踩头,触发逻辑更稳定,不会出现边界判定错误。
问题示意图:
内容的提问来源于stack exchange,提问作者user15664353
相关产品推荐
相关产品推荐

