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

使用Rigidbody MovePosition时3D敌人模型离地漂移问题求助

敌人离地漂移问题解决思路

核心问题分析

使用Rigidbody.MovePosition时直接修改位置会干扰重力的作用,加上受击时的外力影响,容易导致敌人Y轴位置偏离地面。另外部分状态代码存在方向未归一化的问题,会间接加剧移动异常。


具体修复方案

1. 统一约束移动时的Y轴位置

在所有调用MovePosition的状态中,固定Y轴到地面基准高度:

  • 先在敌人初始化时记录地面高度(平面地形适用):

    private float groundY;
    private Rigidbody rb;
    private CapsuleCollider collider;
    
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        collider = GetComponent<CapsuleCollider>();
        // 记录初始地面高度,加上Collider半高防止陷入地面
        groundY = rb.position.y;
    }
    
  • 巡逻状态修改:

    Vector3 direction = (destination - rb.transform.position);
    float distance = Vector3.Distance(rb.transform.position, destination);
    
    direction.y = 0;
    // 计算目标位置后固定Y轴
    Vector3 targetPos = enemy.transform.position + direction.normalized * speed * Time.deltaTime;
    targetPos.y = groundY;
    rb.MovePosition(targetPos);
    
    rb.transform.rotation = Quaternion.Slerp(rb.transform.rotation, Quaternion.LookRotation(direction), Time.deltaTime * rotationSpeed);
    
  • 追击状态修改(同时修复方向未归一化导致的速度异常):

    direction2Player = player.position - enemy.transform.position;
    direction2Player.y = 0;
    // 归一化方向,确保移动速度稳定
    Vector3 targetPos = rb.transform.position + runningSpeed * Time.deltaTime * direction2Player.normalized;
    targetPos.y = groundY;
    rb.MovePosition(targetPos);
    
    rb.transform.rotation = Quaternion.Slerp(rb.transform.rotation, Quaternion.LookRotation(direction2Player), Time.deltaTime * rotationSpeed);
    

2. 实时修正Y轴漂移

在FixedUpdate中持续检查并修正Y轴位置(物理帧同步,避免抖动):

private void FixedUpdate()
{
    // 允许微小误差范围,防止频繁修正导致抖动
    if (Mathf.Abs(rb.position.y - groundY) > 0.05f)
    {
        Vector3 fixedPos = rb.position;
        fixedPos.y = groundY;
        rb.MovePosition(fixedPos);
    }
}

3. 优化Rigidbody设置

  • 将Rigidbody的Collision Detection设为Continuous Dynamic,避免快速移动时地形检测失效;
  • 确保敌人的Collider(推荐CapsuleCollider)尺寸合适,与地形碰撞体有正确的交互;
  • 若不需要敌人在Y轴有物理移动,可勾选Rigidbody的Constraints → Freeze Position Y(但会屏蔽重力,需根据需求选择)。

4. 替换攻击状态的临时修复

移除攻击状态中固定Y值的代码,改用全局的groundY或射线检测动态获取地面高度(适配非绝对平面地形):

public override void Update()
{
    direction2Player = player.position - enemy.transform.position;
    direction2Player.y = 0;

    rb.transform.rotation = Quaternion.Slerp(rb.transform.rotation, Quaternion.LookRotation(direction2Player), Time.deltaTime * rotationSpeed);

    // 移除原固定Y值的代码,改用FixedUpdate中的统一修正
}

内容的提问来源于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 18:34:52