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

Unity中Physics.Raycast的LayerMask未检测到碰撞问题求助

Unity单位移动系统:Physics.Raycast无响应问题排查

问题背景

刚接触Unity,正在开发一套单位移动系统,用于让单位在带Mesh Filter的3D地图对象上跨位置移动。目前发现代码执行到Physics.Raycast语句后便不再继续,无任何报错信息,推测是LayerMask参数导致的问题。已完成移动对象的导航网格烘焙。

问题代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnitCommander : MonoBehaviour
{
    public GameObject selectionMarkerPrefab;
    public LayerMask layerMask;

    // components
    private UnitSelection unitSelection;
    private Camera cam;

    void Awake ()
    {
        // get the components
        unitSelection = GetComponent<UnitSelection>();
        cam = Camera.main;
    }

    void Update ()
    {
        // did we press down our right mouse button and do we have units selected?
        if (Input.GetMouseButtonDown(1) && unitSelection.HasUnitsSelected())
        {
            // shoot a raycast from our mouse, to see what we hit
            Ray ray = cam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            // cache the selected units in an array
            Unit[] selectedUnits = unitSelection.GetSelectedUnits();

            // 临时添加射线可视化,方便调试
            Debug.DrawRay(ray.origin, ray.direction * 100, Color.red);

            // shoot the raycast
            if (Physics.Raycast(ray, out hit, 100, layerMask))
            {
                Debug.LogWarning("Here");
                // are we clicking on the ground?
                if (hit.collider.CompareTag("Sea"))
                {
                    UnitsMoveToPosition(hit.point, selectedUnits);
                    CreateSelectionMarker(hit.point);
                }
            }
        }
    }

    // called when we command units to move somewhere
    void UnitsMoveToPosition (Vector3 movePos, Unit[] units)
    {
        Vector3[] destinations = UnitMover.GetUnitGroupDestinations(movePos, units.Length, 2);

        for(int x = 0; x < units.Length; x++)
        {
            units[x].MoveToPosition(destinations[x]);
        }
    }

    // creates a new selection marker visual at the given position
    void CreateSelectionMarker (Vector3 pos)
    {
        Instantiate(selectionMarkerPrefab, new Vector3(pos.x, 0.01f, pos.z), Quaternion.identity);
    }
}

地图对象设置截图

对象设置截图

排查与解决方法

  • 检查LayerMask Inspector赋值:确保在Unity编辑器的Inspector面板中,UnitCommander组件的layerMask勾选了地图对象所在的Layer(从截图看是Sea层)。如果LayerMask未勾选目标层,射线会完全忽略该对象,导致Physics.Raycast返回false。
  • 临时移除LayerMask测试:把Physics.Raycast的第四个参数去掉,改成Physics.Raycast(ray, out hit, 100),如果此时能触发Debug.LogWarning("Here"),说明确实是LayerMask的设置问题。
  • 确认地图对象有Collider:带Mesh Filter的对象必须添加Mesh Collider组件才能被射线检测到,检查地图对象是否添加了该组件,若Mesh复杂可尝试勾选Convex选项(地形类对象一般无需勾选)。
  • 正确设置LayerMask代码:如果是动态设置LayerMask,使用layerMask = LayerMask.GetMask("Sea")来获取目标层的掩码,避免直接使用Layer数字导致的错误。
  • 可视化射线:代码中已添加Debug.DrawRay,运行游戏后在Scene视图中可以看到红色射线,确认射线是否指向地图对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:55:22