Unity相机相对角色移动异常及跳跃重力失效问题求助
解决方案:实现角色持续跟随相机方向移动+保留跳跃重力功能
问题根源
handleMovement的向量覆盖问题:原函数中直接用currentMovement = 相机方向向量完全覆盖了currentMovement,导致之前通过handleJump和handleGravity设置的y轴速度被清空- 执行顺序错误:原
Update中先调用characterController.Move(),再处理重力和跳跃,导致y轴的速度变化没被应用到移动计算 - 未持续更新相机相对方向:原代码没在
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
相关产品推荐
相关产品推荐

