Unity角色控制器:解决斜向移动与终端重力的兼容问题
Unity Character Controller 移动与重力兼容问题修复方案
问题核心是不能直接归一化整个moveDirection向量——这会把Y轴的重力加速度值也限制在±1范围内,导致重力无法累积到终端速度;但不归一化的话,斜向移动的向量模长会超过1,使得斜移速度快于单方向移动。
修复思路
单独处理XZ平面的移动向量,仅对水平移动分量做归一化,完全保留Y轴的重力计算结果:
- 提取水平输入的XZ分量,生成单独的平面向量
- 仅当该平面向量的模长大于1时进行归一化(避免静止/小幅度输入时的异常)
- 将处理后的XZ分量赋值回
moveDirection,保留原Y轴的重力值
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class PlayerMovementScript : MonoBehaviour { public Vector3 moveDirection = new Vector3(); public float moveSpeed; public float gravityAcceleration; // 重命名变量,更清晰表示重力加速度用途 public float terminalVelocity; CharacterController characterController; void Start() { characterController = GetComponent<CharacterController>() ?? characterController; } void Update() { // 提取水平移动的XZ分量 Vector3 horizontalMove = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); // 仅当水平移动向量模长超过1时归一化,避免小输入被放大 if (horizontalMove.magnitude > 1f) { horizontalMove = horizontalMove.normalized; } // 赋值处理后的XZ分量,保留原Y轴的重力值 moveDirection.x = horizontalMove.x; moveDirection.z = horizontalMove.z; // 重力逻辑保持不变 if (!characterController.isGrounded) { if (moveDirection.y > -terminalVelocity) { moveDirection.y -= Time.deltaTime * gravityAcceleration; } } else { moveDirection.y = -2f; } // 应用移动 characterController.Move(moveDirection * Time.deltaTime * moveSpeed); } }
额外优化说明
- 把原变量
velocity重命名为gravityAcceleration,更贴合其重力加速度的用途,提升代码可读性 - 使用
??空合并运算符简化Start里的CharacterController获取逻辑
内容的提问来源于stack exchange,提问作者1095795
相关产品推荐
相关产品推荐

