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

Unity角色按上箭头键无法每次触发跳跃的问题排查

问题分析与修复方案

你的跳跃触发异常核心原因是直接修改transform.position干扰了CharacterController的内部碰撞状态,导致controller.isGrounded检测不稳定,很多时候按下跳跃键时,角色的接地判断并未生效。此外,车道切换的位置计算逻辑也存在错误,进一步加剧了状态异常。

以下是修复后的完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    private CharacterController controller; 
    private Vector3 direction; 
    public float forwardSpeed; 

    private int desiredLane = 1;//0:left 1:middle 2:right 
    public float laneDistance = 4;// distance between two lanes 

    public float JumpForce;
    public float Gravity = -20; 
    
    void Start()
    {
        controller = GetComponent<CharacterController>(); 
    }

    private void Jump() 
    {
        direction.y = JumpForce; 
    }

    // Update is called once per frame
    void Update()
    {
        direction.z = forwardSpeed;

        // 处理车道切换输入
        if(Input.GetKeyDown(KeyCode.RightArrow)) 
        {
            desiredLane++; 
            desiredLane = Mathf.Clamp(desiredLane, 0, 2);
        }
        
        if(Input.GetKeyDown(KeyCode.LeftArrow)) 
        {
            desiredLane--; 
            desiredLane = Mathf.Clamp(desiredLane, 0, 2);
        }

        // 计算目标车道的X坐标
        float targetX = 0;
        if (desiredLane == 0)
        {
            targetX = -laneDistance;
        }
        else if (desiredLane == 2)
        {
            targetX = laneDistance;
        }
        // 横向移动:平滑修正X轴位置到目标车道
        direction.x = Mathf.Lerp(transform.position.x, targetX, 50 * Time.deltaTime) - transform.position.x;

        // 处理跳跃输入
        if(controller.isGrounded) 
        {   
            // 接地时重置Y方向速度,避免重力累积影响
            direction.y = 0;
            
            if(Input.GetKeyDown(KeyCode.UpArrow)) 
            {
                Jump();
            } 
        }
        else 
        {
            direction.y += Gravity * Time.deltaTime;
        }
    }

    private void FixedUpdate() 
    {
        // 统一用CharacterController.Move处理所有移动,保证状态同步
        controller.Move(direction * Time.fixedDeltaTime);   
    }
}

关键修改点说明

  • 移除直接修改transform.position的代码:改用direction.x来控制横向移动,通过controller.Move统一更新位置,确保CharacterController的碰撞和接地状态始终准确。
  • 修正车道位置计算:直接基于X轴目标值计算横向移动量,避免原代码中错误的向量组合逻辑。
  • 接地时重置Y方向速度:在controller.isGrounded为true时,将direction.y设为0,防止重力累积导致下次跳跃时的状态异常。
  • 简化车道边界判断:用Mathf.Clamp替代手动的边界判断,代码更简洁可靠。

内容的提问来源于stack exchange,提问作者Oleksandr Nikitin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:15