Unity中使用CharacterController跳跃时旋转Y值归零问题求解
问题原因分析
你遇到的旋转Y值归零问题,核心原因是跳跃时moveDirection的X/Z分量为0,但Y分量不为0,导致moveDirection.magnitude >= 0.1f的条件成立,此时Mathf.Atan2(0,0)计算出的targetAngle是0,平滑旋转逻辑会把角色Y轴旋转强制拉到0度。
修复方案
把旋转逻辑和移动逻辑的触发条件彻底分开:旋转只在有水平/垂直输入时执行,而移动(包括重力、跳跃的Y轴移动)始终执行,不受方向输入影响。修改后的完整代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMovement : MonoBehaviour { public CharacterController controller; public float turnSmoothTime = 0.1f; float turnSmoothVelocity; public float Speed = 10f; private Vector3 moveDirection; public float gravity = -9.81f; public float jumpPower = 3.5f; public float directionY; public Animator anim; public Transform cam; private void Update() { float horizontal = Input.GetAxisRaw("Horizontal"); float vertical = Input.GetAxisRaw("Vertical"); // 处理地面检测与跳跃逻辑 if (controller.isGrounded) { directionY = Input.GetKeyDown(KeyCode.Space) ? jumpPower : 0; } else { directionY += gravity * Time.deltaTime; } // 处理方向输入与角色旋转 Vector3 inputDirection = new Vector3(horizontal, 0f, vertical).normalized; if (inputDirection.magnitude >= 0.1f) { float targetAngle = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg; // 如果需要跟随相机视角旋转,取消下面这行注释 // targetAngle += cam.eulerAngles.y; float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime); transform.rotation = Quaternion.Euler(0f, angle, 0f); // 将输入方向转换为世界空间下的移动方向 moveDirection = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward; moveDirection *= Speed; } else { // 无方向输入时,仅保留Y轴的重力/跳跃力,X/Z方向停止移动 moveDirection.x = 0; moveDirection.z = 0; } // 应用Y轴的重力/跳跃力 moveDirection.y = directionY; // 执行移动(始终调用,确保跳跃和重力生效) controller.Move(moveDirection * Time.deltaTime); // 动画状态更新(可选) bool isWalking = !Mathf.Approximately(horizontal, 0f) || !Mathf.Approximately(vertical, 0f); anim.SetBool("IsWalking", isWalking); } }
关键修改点
- 拆分
inputDirection(仅存储X/Z轴的玩家输入方向)与moveDirection(最终移动方向,包含Y轴的重力/跳跃力),旋转逻辑仅依赖inputDirection,彻底避免Y轴分量干扰旋转判断 - 将
controller.Move改为始终调用,确保跳跃、重力的Y轴移动不受方向输入影响 - 无方向输入时,强制将
moveDirection的X/Z分量设为0,避免无输入时的无效移动
内容的提问来源于stack exchange,提问作者Unityabcd
相关产品推荐
相关产品推荐

