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

Unity相机相对角色移动异常及跳跃重力失效问题求助

解决方案:实现角色持续跟随相机方向移动+保留跳跃重力功能

问题根源

  1. handleMovement的向量覆盖问题:原函数中直接用currentMovement = 相机方向向量完全覆盖了currentMovement,导致之前通过handleJump和handleGravity设置的y轴速度被清空
  2. 执行顺序错误:原Update中先调用characterController.Move(),再处理重力和跳跃,导致y轴的速度变化没被应用到移动计算
  3. 未持续更新相机相对方向:原代码没在Update中调用handleMovement,只有输入变化时才更新移动方向,无法实时跟随相机转向

修改后的关键代码

1. 修复handleMovement函数(保留y轴速度)

void handleMovement()
{
    // 先基于输入计算本地空间的x/z速度
    float moveX = currentMovementInput.x * (isRunPressed ? RunSpeed : moveSpeed);
    float moveZ = currentMovementInput.y * (isRunPressed ? RunSpeed : moveSpeed);

    // 转换为相机相对的世界空间方向,保留原y轴值(跳跃/重力)
    Vector3 cameraRelativeMovement = cameraTransform.right.normalized * moveX + cameraTransform.forward.normalized * moveZ;
    cameraRelativeMovement.y = currentMovement.y; // 保留y轴的速度

    currentMovement = cameraRelativeMovement;
    isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}

2. 调整Update函数的执行顺序(先处理所有速度,再执行移动)

void Update()
{
    handleAnimation();
    handleRotation();
    handleAttacking();
    
    // 攻击冷却逻辑保留
    if(cooldownStart)
    {
        attackCountSpeed += Time.deltaTime;
    }
    if(attackCountSpeed > 2.0f)
    {
        cooldownStart = false;
        attackCountSpeed = 1f;
        attackCount = 0;
    }

    // 每帧更新相机相对移动方向
    handleMovement();

    // 应用移动速度(包含x/z的相机相对方向和y轴的重力/跳跃)
    appliedMovement = currentMovement;

    // 先处理重力和跳跃,更新y轴速度
    handleGravity();
    handleJump();

    // 最后执行移动,确保所有速度都已更新
    if(isAttackAnimate && Attack_2Animate && !stopMove)
    {
        characterController.Move(appliedMovement * Time.deltaTime);
    }
}

3. 修正handleGravity和handleJump的赋值逻辑

void handleJump()
{
    if(!isJumping && characterController.isGrounded && isJumpPressed)
    {
        animator.SetBool(isJumpingHash, true);
        isJumpAnimating = true;
        isJumping = true;
        currentMovement.y = initialJumpingVelocity;
        appliedMovement.y = initialJumpingVelocity;
    }
    else if(isJumping && characterController.isGrounded && !isJumpPressed)
    {
        isJumping = false;
    }
}

void handleGravity()
{
    bool isFalling = currentMovement.y <= 0.0f || !isJumpPressed;
    float fallMultiplier = 2.0f;
    
    if(characterController.isGrounded)
    {
        if(isJumpAnimating)
        {
            animator.SetBool(isJumpingHash, false);
            isJumpAnimating = false;
        }
        currentMovement.y = GroundedGravity;
        appliedMovement.y = GroundedGravity;
    }
    else if(isFalling)
    {
        float previousYVelocity = currentMovement.y;
        currentMovement.y += Gravity * fallMultiplier * Time.deltaTime;
        appliedMovement.y = Mathf.Max((previousYVelocity + currentMovement.y) * 0.5f, -20f);
    }
    else
    {
        float previousYVelocity = currentMovement.y;
        currentMovement.y += Gravity * Time.deltaTime;
        appliedMovement.y = (previousYVelocity + currentMovement.y) * 0.5f;
    }
}

关键改动说明

  • 保留y轴速度:在计算相机相对移动时,专门把原currentMovement.y赋值给新的向量,避免跳跃/重力的y值被清空
  • 正确的执行顺序:先更新移动方向,再处理重力和跳跃,最后调用characterController.Move(),确保所有速度变化都被应用
  • 持续更新方向:每帧调用handleMovement,保证角色方向实时跟随相机转向
  • 简化速度赋值:直接把currentMovement赋值给appliedMovement,避免分开赋值x/z时遗漏y轴

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:02:04