Unity2D Sprite碰撞未检测、敌人受推后持续移动问题求助
问题1:碰撞未触发、玩家不扣血的解决方案
- 核心代码错误:Unity 2D物理系统的碰撞进入回调正确名称是
OnCollisionEnter2D,你代码中写的OnCollision是3D物理的回调函数,永远不会被触发,自然不会输出Log也不会执行扣血逻辑。 - 标签匹配错误:你在触发检测逻辑中使用的玩家标签是首字母大写的
"Player",但碰撞检测中用的是全小写的"player",就算回调函数写对也匹配不到玩家对象。 - 额外场景配置检查:敌方和玩家对象都要挂载
Collider2D组件且均未勾选Is Trigger属性(勾选Trigger后只会触发Trigger类回调,不会触发Collision类回调);两个对象中至少有一个挂载Rigidbody2D组件,这是Unity 2D物理碰撞生效的必要条件。
修正后的碰撞回调代码参考:
private void OnCollisionEnter2D(Collision2D other) { if (other.gameObject.tag == "Player") { Debug.Log("hit"); other.gameObject.GetComponent<PlayerHealth>().UpdateHealth(attackDamage); } }
问题2:敌人被推动后一直滑行的解决方案
这个问题由两个原因共同导致:
- 你直接修改
transform.position移动敌人,该方式会绕过Unity物理引擎的运动计算,碰撞产生的速度没有被正常消耗,所以会一直保持运动状态。 - 敌人挂载的
Rigidbody2D组件的Linear Drag(线性阻尼)默认值为0,没有模拟摩擦力的效果。
修正方案:
- 改用
Rigidbody2D.MovePosition方法实现移动,物理相关操作统一放在FixedUpdate中执行,符合Unity物理更新规则。 - 在Inspector面板把敌人
Rigidbody2D组件的Linear Drag值调整到2~5之间,模拟运动摩擦力。
修正后的移动逻辑代码参考:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy: MonoBehaviour { public float speed = 3f; private Transform target; [SerializeField] private float attackDamage = -10f; // 新增刚体变量 private Rigidbody2D rb; private void Awake() { // 初始化刚体引用 rb = GetComponent<Rigidbody2D>(); } // 物理操作移到FixedUpdate执行 private void FixedUpdate(){ if (target != null){ float step = speed * Time.fixedDeltaTime; rb.MovePosition(Vector2.MoveTowards(transform.position, target.position, step)); } } private void OnCollisionEnter2D(Collision2D other){ if (other.gameObject.tag == "Player"){ Debug.Log("hit"); other.gameObject.GetComponent<PlayerHealth>().UpdateHealth(attackDamage); } } private void OnTriggerEnter2D(Collider2D other) { if(other.gameObject.tag == "Player"){ target = other.transform; Debug.Log(target); } } private void OnTriggerExit2D(Collider2D other) { if(other.gameObject.tag == "Player"){ target = null; Debug.Log(target); } } }
内容的提问来源于stack exchange,提问作者Pena Plays
相关产品推荐
相关产品推荐

