Unity移动脚本跳跃功能失效问题求助
问题分析与解决方案
你的代码核心问题是角色接地时没有重置垂直速度,导致重力持续累加出一个很大的负向速度,即使跳跃给了向上的速度,也会瞬间被抵消,看起来就像没跳起来。另外还有一处冗余变量可以优化。
关键修复点
- 当
CharacterController.isGrounded为true时,必须重置_playerVelocity.y为一个极小的负值(比如-0.1f),而不是让它一直累加重力。这样能保证跳跃时的向上速度不会被之前累积的向下速度覆盖。 - 统一冗余的速度变量(你同时定义了
speed和playerSpeed,但移动逻辑只用了speed,可以删除playerSpeed避免混淆)。
修改后的完整代码
using UnityEngine; public class Testing : MonoBehaviour { public CharacterController controller; public Transform cam; public float speed = 6f; private float _turnSmoothVelocity; private bool _groundedPlayer; public float turnSmoothTime = 0.1f; // 跳跃高度 public float jumpHeight = 1.0f; // 重力值 public float gravityValue = -9.81f; // 当前速度 private Vector3 _playerVelocity; void Start() { // 删除未使用的_playerTransform变量 } private void Update() { _groundedPlayer = controller.isGrounded; // 关键修复:接地时重置垂直速度,保持微小向下力确保接地检测正常 if (_groundedPlayer && _playerVelocity.y < 0) { _playerVelocity.y = -0.1f; } var horizontal = Input.GetAxisRaw("Horizontal"); var vertical = Input.GetAxisRaw("Vertical"); var direction = new Vector3(horizontal, 0f, vertical).normalized; if (direction.magnitude >= 0.1f) { var targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y; var angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref _turnSmoothVelocity, turnSmoothTime); transform.rotation = Quaternion.Euler(0f, angle, 0f); var moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward; controller.Move(moveDir.normalized * speed * Time.deltaTime); } if (Input.GetButtonDown("Jump") && _groundedPlayer) { Debug.Log("Grounded player && jump button pressed"); // 标准跳跃速度计算公式:sqrt(2 * 跳跃高度 * -重力),保证跳跃高度与设置值匹配 _playerVelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravityValue); } // 应用重力 _playerVelocity.y += gravityValue * Time.deltaTime; // 应用垂直方向移动 controller.Move(_playerVelocity * Time.deltaTime); } }
额外说明
- 把跳跃公式从
*3.0f改成*2.0f是遵循物理标准公式v = sqrt(2gh),这样计算出的跳跃速度能让角色刚好跳到你设置的jumpHeight高度。 - 删除了未使用的
_playerTransform变量,简化代码结构。
内容的提问来源于stack exchange,提问作者Tyler Critchlow
相关产品推荐
相关产品推荐

