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

Unity 2D:如何让追踪目标的敌人通过射线检测避开障碍物

敌人绕开障碍物的实现方案

针对你遇到的敌人被方形障碍物卡住的问题,这里提供几种基于现有射线检测的实现思路:

方法一:偏移目标方向(简单快速)

当射线检测到障碍物时,利用障碍物表面的法向量调整目标方向,让敌人向远离障碍物的偏移方向移动:

// 假设已通过射线得到hit对象(RaycastHit2D hit)
if (hit.collider != null)
{
    // 获取障碍物表面的法向量(垂直于障碍物的方向)
    Vector2 obstacleNormal = hit.normal;
    // 计算偏移量,系数可根据障碍物大小调整
    Vector2 avoidOffset = obstacleNormal * 1.5f;
    // 调整目标方向向量,加入偏移量后归一化
    toVec = (targetPos - rb.position + avoidOffset).normalized;
}

// 应用最终移动速度
rb.velocity = toVec * moveSpeed;

核心逻辑:通过法向量让敌人避开障碍物表面,避免直接碰撞,适配大多数简单场景。

方法二:添加侧向躲避力(物理驱动更自然)

不直接修改目标方向,而是给敌人施加侧向力,让它在保持追踪趋势的同时绕开障碍物:

if (hit.collider != null)
{
    // 计算敌人指向障碍物的向量
    Vector2 toObstacle = hit.point - rb.position;
    // 生成两个垂直于障碍物的候选躲避方向
    Vector2 avoidDirLeft = new Vector2(-toObstacle.y, toObstacle.x).normalized;
    Vector2 avoidDirRight = new Vector2(toObstacle.y, -toObstacle.x).normalized;
    
    // 选择更靠近原目标方向的躲避方向
    Vector2 finalAvoidDir = Vector2.Dot(avoidDirLeft, toVec) > Vector2.Dot(avoidDirRight, toVec) ? avoidDirLeft : avoidDirRight;
    
    // 添加躲避力并归一化速度,保证总移动速度不变
    rb.velocity += finalAvoidDir * moveSpeed * 0.5f;
    rb.velocity = rb.velocity.normalized * moveSpeed;
}
else
{
    // 无障碍物时正常追踪目标
    rb.velocity = toVec.normalized * moveSpeed;
}

核心逻辑:利用物理力实现自然躲避,敌人会根据目标位置自动选择更优的绕路方向。

方法三:临时目标点绕路(适配固定方形障碍物)

针对固定的方形障碍物,预先计算其四个角落坐标,选择最优角落作为临时目标,绕过后再恢复追踪:

// 假设障碍物的Transform为obstacleTransform,获取四个角落的世界坐标
Vector2[] obstacleCorners = new Vector2[4];
obstacleCorners[0] = obstacleTransform.TransformPoint(new Vector2(-0.5f, -0.5f)); // 左下
obstacleCorners[1] = obstacleTransform.TransformPoint(new Vector2(0.5f, -0.5f));  // 右下
obstacleCorners[2] = obstacleTransform.TransformPoint(new Vector2(0.5f, 0.5f));   // 右上
obstacleCorners[3] = obstacleTransform.TransformPoint(new Vector2(-0.5f, 0.5f));  // 左上

// 筛选出"敌人到角落+角落到目标"总距离最短的角落
Vector2 bestCorner = obstacleCorners[0];
float minTotalDist = float.MaxValue;
foreach (var corner in obstacleCorners)
{
    float totalDist = Vector2.Distance(rb.position, corner) + Vector2.Distance(corner, targetPos);
    if (totalDist < minTotalDist)
    {
        minTotalDist = totalDist;
        bestCorner = corner;
    }
}

// 先向临时角落移动
toVec = (bestCorner - rb.position).normalized;

// 到达角落附近后,恢复追踪原目标
if (Vector2.Distance(rb.position, bestCorner) < 0.3f)
{
    toVec = (targetPos - rb.position).normalized;
}

// 应用移动速度
rb.velocity = toVec * moveSpeed;

核心逻辑:通过固定绕路点实现精准绕开,适合场景中位置固定的障碍物。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:50:35