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

使用Rigidbody.MovePosition移动敌人出现穿模,求碰撞检测解决方案

问题解决:敌人沿路径点移动时的碰撞与推挤实现

问题描述

我希望让模型能够识别碰撞并避开玩家等物体。我发现Navmesh Agent无法检测物理碰撞,因此改用Rigidbody.MovePosition让敌人沿路径点移动,但它会穿过路径上的所有物体。敌人和测试对象都带有Capsule Collider与Rigidbody组件。我并非专业开发者,恳请提供帮助,我希望敌人能与物体产生碰撞并推开它们。

解决思路与修改方案

  • 放弃直接硬赋值位置:Rigidbody.MovePosition是直接强制设置刚体位置,不会触发物理引擎的碰撞交互(除非开启运动学,但运动学刚体无法被其他物体推开)。必须改用物理驱动的方式移动。
  • 检查核心组件设置:
    • 敌人的Rigidbody要关闭Is Kinematic选项,确保参与物理碰撞
    • 给敌人设置合理的Mass值(比如2-5),质量越大推挤其他物体的效果越明显
    • 确保双方的Capsule Collider都关闭Is Trigger,触发器不会产生物理碰撞
  • 用物理驱动替代硬移动:通过设置刚体速度或施加力的方式让敌人移动,交给物理引擎处理碰撞逻辑

修改后的完整代码

public List<GameObject> waypoints;
public Rigidbody rb;
int index = 0;
public float speed = 2f;
Animator animator;

void Start()
{
    rb = GetComponent<Rigidbody>();
    animator = GetComponent<Animator>();
    // 强制关闭运动学,确保物理交互生效
    rb.isKinematic = false;
}

void FixedUpdate()
{
    Vector3 destination = waypoints[index].transform.position;
    // 归一化方向向量,避免距离远近影响移动速度
    Vector3 direction = (destination - transform.position).normalized;
    float distance = Vector3.Distance(rb.transform.position, destination);

    // 用速度驱动移动,让物理引擎处理碰撞
    rb.velocity = direction * speed;
    
    // 平滑看向目标方向,避免近距离旋转抖动
    if (direction.magnitude > 0.1f)
    {
        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(direction), Time.deltaTime * 5f);
    }

    // 到达路径点后切换下一个目标
    if (distance <= 1)
    {
        index++;
        if (index >= waypoints.Count)
        {
            index = 0;
        }
    }
}

额外注意事项

  • 测试对象的Rigidbody同样要关闭Is Kinematic,并设置合适的质量,才能被敌人成功推开
  • 如果需要更精准的路径跟随+避障,后续可以考虑结合NavMeshObstacle组件,或者用Rigidbody.AddForce替代直接设置速度,获得更自然的物理反馈

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:10:10