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

Unity 2D中Raycast无法检测静止对象问题求助

2D平台敌人移动转向问题修复方案

问题还原

开发Unity 2D平台游戏时,尝试实现敌人(史莱姆)向前移动、碰到墙体/平台边缘转向的功能,编写了原型脚本后出现以下异常:

  • 史莱姆仅在玩家移动时能检测到玩家,且仅当玩家碰撞到射线原点时才触发检测
  • 进入地面数秒后才会检测到地面,调大射线长度也无效
    当前配置:刚体设为运动学,盒碰撞器启用触发器

原脚本:

public float speed;
public float raylength;
private Rigidbody2D rb;
private int dir = -1;
// Start is called before the first frame update
void Start()
{
    rb = GetComponent<Rigidbody2D>();
}

// Update is called once per frame
void FixedUpdate()
{
    rb.velocity = new Vector2(speed * dir, rb.velocity.y);
    RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(dir, 0), raylength);
    if(hit.collider != null && hit.collider.gameObject.name!="Slime")
        print(hit.collider.gameObject.name);
    if (hit.collider.gameObject.tag=="Ground")
    {
        dir*=-1;
    }
}

核心问题分析

  1. 运动学刚体移动逻辑错误:运动学刚体不受物理引擎驱动,手动修改velocity不会生效,导致移动延迟或异常,进而干扰射线检测时机
  2. 射线检测默认忽略触发器:Physics2D.Raycast默认不检测启用触发器的碰撞体,而你的地面、玩家碰撞器都是触发器,因此无法正常检测
  3. 缺少平台边缘检测:原脚本只有向前的射线,无法识别平台边缘,敌人不会在边缘处转向
  4. 空引用风险:未判断hit.collider是否为null就访问gameObject.tag,会引发隐性错误

修复步骤

一、调整刚体与碰撞器配置

  • 若无需运动学刚体,直接将刚体改为动态,并勾选Freeze Rotation Z防止敌人旋转;如果必须用运动学,后续移动改用MovePosition方法
  • 关闭盒碰撞器的触发器选项(除非需要触发特定事件,比如敌人碰到玩家造成伤害);如果保留触发器,射线检测时必须添加QueryTriggerInteraction.Collide参数

二、修改脚本逻辑

以下是修复后的完整脚本,包含障碍物检测、边缘检测、适配不同刚体类型的移动逻辑:

public float speed;
public float rayLength;
// 根据敌人碰撞器大小调整,用于边缘检测的射线偏移
public Vector2 edgeRayOffset = new Vector2(0.4f, 0.5f);
private Rigidbody2D rb;
private int dir = -1;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    // 动态刚体配置:设置重力、冻结旋转
    if (!rb.isKinematic)
    {
        rb.gravityScale = 3f;
        rb.freezeRotation = true;
    }
}

void FixedUpdate()
{
    // 根据刚体类型选择正确的移动方式
    if (rb.isKinematic)
    {
        Vector2 newPosition = rb.position + new Vector2(speed * dir * Time.fixedDeltaTime, 0);
        rb.MovePosition(newPosition);
    }
    else
    {
        rb.velocity = new Vector2(speed * dir, rb.velocity.y);
    }

    // 1. 前方障碍物检测:指定检测层并允许检测触发器
    int groundLayer = LayerMask.GetMask("Ground");
    int playerLayer = LayerMask.GetMask("Player");
    int detectLayers = groundLayer | playerLayer;

    RaycastHit2D frontHit = Physics2D.Raycast(transform.position, 
                                              Vector2.right * dir, 
                                              rayLength, 
                                              detectLayers,
                                              QueryTriggerInteraction.Collide);

    // 2. 平台边缘检测:从敌人底部两侧发射向下射线
    RaycastHit2D leftEdgeHit = Physics2D.Raycast(transform.position + new Vector2(-edgeRayOffset.x, -edgeRayOffset.y), 
                                                 Vector2.down, 
                                                 rayLength, 
                                                 groundLayer,
                                                 QueryTriggerInteraction.Collide);
    RaycastHit2D rightEdgeHit = Physics2D.Raycast(transform.position + new Vector2(edgeRayOffset.x, -edgeRayOffset.y), 
                                                  Vector2.down, 
                                                  rayLength, 
                                                  groundLayer,
                                                  QueryTriggerInteraction.Collide);

    // 判断是否需要转向
    bool needTurn = false;
    // 前方碰到地面障碍物
    if (frontHit.collider != null && frontHit.collider.CompareTag("Ground"))
    {
        needTurn = true;
    }
    // 向左移动时,左侧脚下无地面(边缘)
    if (dir == -1 && !leftEdgeHit)
    {
        needTurn = true;
    }
    // 向右移动时,右侧脚下无地面(边缘)
    if (dir == 1 && !rightEdgeHit)
    {
        needTurn = true;
    }

    if (needTurn)
    {
        dir *= -1;
    }

    // 调试打印(可选保留)
    if (frontHit.collider != null && frontHit.collider.gameObject.name != "Slime")
    {
        Debug.Log(frontHit.collider.gameObject.name);
    }
}

三、编辑器配套设置

  • 给地面对象设置Ground标签,玩家对象设置Player标签
  • 在Layer面板中添加Ground和Player层,并给对应对象分配层级
  • 调整edgeRayOffset的值,确保射线从敌人碰撞器的底部两侧发射,准确检测平台边缘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:54:53