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

Unity 3D跟随机器人无法正确追踪玩家,出现原地振动绕圈问题

问题描述

场景中有两台带盒碰撞体的3D刚体机器人,其中一台挂载以下脚本实现无旋转跟随并推挤另一台:

public class BotFollowSwerve : MonoBehaviour
{
    public Transform target;
    public float force = 10f;

    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        Vector3 targetDirection = (target.position - transform.position).normalized;

        rb.AddForce(targetDirection * force, ForceMode.Force);
    }
}

另一台由玩家操控,支持旋转和移动,出现以下异常:

  • 玩家机器人背对跟随机器人时,跟随机器人会停在约2个机身长度的位置,原地振动或绕圈
  • 玩家机器人仅移动不旋转时,跟随机器人能保持距离正常跟随
  • 玩家机器人转向跟随机器人时,跟随机器人可正常跟随并推挤

已确认targetDirection并非零向量,排除该因素导致的问题。

问题原因与解决方法

核心原因

当玩家机器人背对时,跟随机器人的推进力指向玩家机器人中心,但两者盒碰撞体产生的排斥力与推进力形成动态平衡,再加上刚体物理特性(如摩擦力、碰撞检测帧间误差)的影响,导致跟随机器人在平衡点附近反复来回,出现振动/绕圈现象。

修复方案

1. 添加最小跟随距离阈值

设置一个最小距离,当跟随机器人与目标的距离小于该值时停止施力,避免持续的力与碰撞排斥力对抗:

public float minFollowDistance = 1.5f; // 根据实际机身长度调整

void FixedUpdate()
{
    float distanceToTarget = Vector3.Distance(target.position, transform.position);
    if (distanceToTarget > minFollowDistance)
    {
        Vector3 targetDirection = (target.position - transform.position).normalized;
        rb.AddForce(targetDirection * force, ForceMode.Force);
    }
}

2. 调整力的施加方式或限制最大速度

持续使用ForceMode.Force容易让刚体在平衡点反复加速减速,改用脉冲力或限制最大速度可缓解振动:

public float maxSpeed = 5f;

void FixedUpdate()
{
    Vector3 targetDirection = (target.position - transform.position).normalized;
    // 限制最大速度,避免过度加速导致碰撞后反弹振动
    if (rb.velocity.magnitude < maxSpeed)
    {
        rb.AddForce(targetDirection * force, ForceMode.Force);
    }
    // 可选:改用脉冲力,降低施力频率(适合不需要持续推力的场景)
    // rb.AddForce(targetDirection * force * Time.fixedDeltaTime, ForceMode.Impulse);
}

3. 优化碰撞体物理设置

  • 给两台机器人的碰撞体添加PhysicsMaterial,适当降低静摩擦力和动摩擦力,减少碰撞时的卡顿与异常反弹
  • 调整碰撞体的大小和位置,确保碰撞检测精准,避免因碰撞体偏移导致的错误排斥力

4. 增加轻微转向逻辑(可选)

如果允许跟随机器人轻微旋转,添加转向逻辑让其朝向目标方向,减少侧面碰撞的概率,进一步缓解振动:

public float turnSpeed = 5f;

void FixedUpdate()
{
    Vector3 targetDirection = (target.position - transform.position).normalized;
    // 平滑转向目标方向
    Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSpeed * Time.fixedDeltaTime);
    // 沿自身前方施加推力,避免侧面碰撞
    rb.AddForce(transform.forward * force, ForceMode.Force);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:23:26