Unity FPS玩家控制器跳跃卡顿无报错问题求助
FPS控制器跳跃卡顿问题解决方案
问题根源分析
你的跳跃卡顿主要来自两个核心问题:
- 地面检测时强制重置垂直速度,导致跳跃初速度被意外覆盖
- 两次调用
CharacterController.Move,导致帧内位置更新不连贯,引发卡顿
具体修复步骤
- 修复地面速度重置逻辑:仅当玩家在地面且垂直速度向下时,才重置垂直速度为小负数(保持贴地),避免覆盖跳跃的正速度
- 合并移动调用:将水平移动和垂直速度合并为一个向量,只调用一次
Move,确保位置更新的连贯性 - 优化变量类型(可选):将
Speed从int改为float,方便更精细的速度调整
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FirstPersonController : MonoBehaviour { public CharacterController controller; public Transform groundCheck; public LayerMask groundMask; public float Speed = 5f; // 改为float类型,便于精细调整 public float SprintMultiplier = 2f; public float gravity = -9.81f; public float JumpHeight = 2f; public float groundDistance = 0.4f; private float SprintSpeed = 1f; private float HorizontalInput; private float ForwardInput; bool isOnGround; // 修正命名规范,提升可读性 Vector3 velocity; void Start() { Cursor.lockState = CursorLockMode.Locked; } void Update() { // 检测是否处于地面 isOnGround = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask); // 仅当在地面且垂直速度向下时,重置速度保持贴地,避免覆盖跳跃正速度 if (isOnGround && velocity.y < 0) { velocity.y = -2f; } // 处理跳跃输入 if (Input.GetButtonDown("Jump") && isOnGround) { velocity.y = Mathf.Sqrt(JumpHeight * -2f * gravity); } // 处理冲刺逻辑 SprintSpeed = Input.GetButton("Sprint") && isOnGround ? SprintMultiplier : 1f; // 获取水平/垂直移动输入 HorizontalInput = Input.GetAxis("Horizontal"); ForwardInput = Input.GetAxis("Vertical"); // 计算水平移动方向 Vector3 move = transform.right * HorizontalInput + transform.forward * ForwardInput; // 累加重力到垂直速度 velocity.y += gravity * Time.deltaTime; // 合并水平移动与垂直速度,单次调用Move保证位置更新连贯 Vector3 totalMovement = move.normalized * Speed * SprintSpeed * Time.deltaTime + velocity * Time.deltaTime; controller.Move(totalMovement); } }
额外注意事项
- 确保
groundCheck的位置紧贴CharacterController底部,避免因检测范围过大导致跳跃初期仍被判定为在地面 - 若仍有轻微卡顿,可尝试将
Input.GetAxis替换为Input.GetAxisRaw(会丢失输入平滑效果,按需选择)
内容的提问来源于stack exchange,提问作者user20880796
相关产品推荐
相关产品推荐

