You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Unity中Raycast 2D正确检测Tilemap?

Unity Tilemap射线检测不稳定问题排查与修复

问题描述

使用Physics2D.Raycast检测带Tilemap Collider 2D和Composite Collider 2D的Tilemap,已给墙体Tilemap设置「CollideLayer」标签,但检测结果不稳定:首次测试仅原点能检测到,其他位置无响应;第二次测试完全失效。另一段基于鼠标位置的射线检测脚本表现同样异常。禁用地面Tilemap的碰撞体后,墙体检测恢复正常,推测存在碰撞体干扰或Layer Mask设置问题。

涉及代码

第一段射线检测代码

void Update()
{
    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.up, 4f);
    Debug.DrawRay(transform.position, Vector2.up * 4f, Color.red);
    if (hit.collider != null)
    {
        if (hit.collider.tag == "CollideLayer")
        {
            Debug.Log(hit.collider.name);
        }
    }
}

第二段鼠标位置关联的检测代码

public class BeaconBehaviour : MonoBehaviour {

 public Tilemap map;
 void Update()
 {
     Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
     Vector3Int mouseToCell = map.WorldToCell(new Vector3(mousePosition.x, mousePosition.y, 0));
     Vector3 getCenterCell = map.GetCellCenterWorld(mouseToCell);

     RaycastHit2D hit = Physics2D.Raycast(getCenterCell, Vector2.up, 4f);
     Debug.DrawRay(getCenterCell, Vector2.up * 4f, Color.red);

     if (hit.collider != null)
     {
         // Debug.Log("hitting " + hit.collider.name);
         if (hit.collider.tag == "CollideLayer")
         {
             Debug.Log(hit.collider.name);
         }
     }
     transform.position = getCenterCell;
 }

 private void OnTriggerEnter2D(Collider2D other)
 {
     // Debug.Log(other.gameObject.name);
 }

 private void OnTriggerExit2D(Collider2D other)
 {
     // Debug.Log(other.gameObject.name + " not touching" );
 }
}

排查与修复方案

  • 精准过滤检测目标:使用Layer Mask
    标签仅用于标识物体,射线检测时应通过Layer Mask指定只检测墙体Tilemap所在的Layer(注意区分标签和Layer,二者是不同概念)。修改代码如下:

    // 在Inspector面板给墙体Tilemap指定专属Layer(如WallLayer),然后将该Layer赋值给wallLayer变量
    public LayerMask wallLayer;
    
    void Update()
    {
        // 最后一个参数传入LayerMask,只检测目标Layer
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.up, 4f, wallLayer);
        Debug.DrawRay(transform.position, Vector2.up * 4f, Color.red);
        if (hit.collider != null)
        {
            Debug.Log(hit.collider.name);
        }
    }
    
  • 检查Composite Collider 2D配置
    确保墙体Tilemap的Tilemap Collider 2D勾选了「Used By Composite」,且Composite Collider 2D的「Is Trigger」未被误勾选(Trigger不会被普通Raycast检测到)。

  • 修正射线起点位置偏差
    2D游戏中使用ScreenToWorldPoint时,需设置正确的z值(取Camera的nearClipPlane,避免位置偏移),修改第二段代码中的鼠标位置转换:

    Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    mousePosition.z = Camera.main.nearClipPlane; // 修正z轴位置
    Vector3Int mouseToCell = map.WorldToCell(mousePosition);
    
  • 排查碰撞体重叠干扰
    若地面与墙体Tilemap的碰撞体重叠,射线会优先检测到排序靠前的碰撞体。可调整Tilemap的排序层,或通过Layer Mask彻底排除地面Layer的检测。

  • 添加Debug信息定位问题
    在射线检测后打印详细信息,确认检测到的物体:

    if (hit.collider != null)
    {
        Debug.Log($"检测到:{hit.collider.name} | 标签:{hit.collider.tag} | Layer:{LayerMask.LayerToName(hit.collider.gameObject.layer)}");
    }
    

内容的提问来源于stack exchange,提问作者winnieTheWind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:30:49