Unity中Physics2D.RaycastAll无法检测所有碰撞问题求助
Physics2D.RaycastAll 无法检测到所有碰撞问题修复方案
直接对应你代码的问题和解决方法如下:
- 参数逻辑错误(最高概率原因)
Physics2D.RaycastAll第二个参数要求传入方向向量,但你当前传入的是坐标点,完全不符合参数要求,射线发射方向和你Debug.DrawLine画的参考线方向完全不一致,自然检测不到预期碰撞体。
同时你传入的层级参数8是错误用法:Unity的LayerMask是位掩码,如果你要检测第8层,正确写法是1 << 8,直接写8相当于检测第3层(2的3次方等于8),会匹配不到对应层级的碰撞体。 - 代码笔误
在PlayerState.CarryingRaw分支的循环逻辑中,你写的pickedUpRawItems.Add(hit.transform.gameObject);里的hit是外部作用域的变量,当前循环里的正确变量名是hits[i],这个错误会导致哪怕射线检测到了物体,也无法正确添加到列表里,甚至触发空引用报错。 - 碰撞体配置排查
- 如果被检测物体用的是Trigger碰撞体,需要到「项目设置 > 物理2D」里确认开启
Queries Hit Triggers选项,否则射线默认不会检测Trigger碰撞体 - 确认你要检测的物体的Collider2D没有被之前的逻辑提前禁用,你代码里检测到物体就会把对应Collider2D关掉,后续射线无法再次检测到
- 避免射线起点落在碰撞体内部:Unity 2D射线默认不会返回起点所在的碰撞体,可以把射线起点往发射方向挪0.1单位规避这个问题
- 如果被检测物体用的是Trigger碰撞体,需要到「项目设置 > 物理2D」里确认开启
修正后参考代码
case (PlayerState.CarryingRaw): // 先计算正确的射线方向和距离 Vector2 targetPos = new Vector2(pos.x -5, pos.y); Vector2 rayDir = (targetPos - (Vector2)transform.position).normalized; float rayDistance = Vector2.Distance(transform.position, targetPos); // 层级参数改为位掩码写法,如果你要检测多层可以按位或:1<<8 | 1<<3 hits = Physics2D.RaycastAll(transform.position, rayDir, rayDistance, 1<<8); Debug.DrawLine(transform.position, targetPos, Color.red, 2); for (int i = 0; i < hits.Length; i++) { Debug.Log(hits[i].transform.name); } for (int i = 0; i < hits.Length; i++) { if (hits[i].transform.tag == pickedUpRawItems[pickedUpRawItems.Count - 1].transform.tag) { Debug.Log(hits[i].transform.tag); Debug.Log(pickedUpRawItems[pickedUpRawItems.Count - 1].transform.tag); hits[i].transform.GetComponent<BoxCollider2D>().enabled = false; hits[i].transform.GetComponent<ItemScript>().currentState = ItemScript.ObjectState.PickedUp; hits[i].transform.localScale = sizeChange; // 修正变量名错误 pickedUpRawItems.Add(hits[i].transform.gameObject); } } break; case (PlayerState.Working): break; case (PlayerState.Free): Debug.Log("youhou + State.Free"); Vector2 freeTargetPos = new Vector2(pos.x -5, pos.y); Vector2 freeRayDir = (freeTargetPos - (Vector2)transform.position).normalized; hit = Physics2D.Raycast(transform.position, freeRayDir); if (hit) { hit.transform.GetComponent<BoxCollider2D>().enabled = false; Debug.Log("youhou + hit.Free"); hit.transform.GetComponent<ItemScript>().currentState = ItemScript.ObjectState.PickedUp; hit.transform.localScale = sizeChange; pickedUpRawItems.Add(hit.transform.gameObject); currentState = PlayerState.CarryingRaw; } break;
内容的提问来源于stack exchange,提问作者Aziz Goumiri
相关产品推荐
相关产品推荐

