You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity FPS玩家控制器跳跃卡顿无报错问题求助

FPS控制器跳跃卡顿问题解决方案

问题根源分析

你的跳跃卡顿主要来自两个核心问题:

  1. 地面检测时强制重置垂直速度,导致跳跃初速度被意外覆盖
  2. 两次调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:44:52