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

遵循Brackeys教程的Unity第一人称控制器无法跳跃求助

Unity第一人称控制器无法跳跃(isGrounded判断异常)

问题还原

按照Brackeys的Unity第一人称控制器教程实现后,出现以下问题:

  • 保留跳跃判断中的isGrounded条件时,角色完全无法跳跃;
  • 移除该条件后,角色可以跳跃但会无限起跳;
  • 已尝试修改地面检测方式(Physics.CheckSphere改Physics.Raycast)、移除重力代码、删除地面检测逻辑,且确认地面层设置正确、GroundCheck引用正常、遮罩选择无误,但问题仍未解决。

排查与解决方案

1. 先确认isGrounded的真实状态

在Update中添加调试代码,实时打印isGrounded的值,判断是检测逻辑失效还是跳跃逻辑冲突:

void Update()
{
    // 保留你的地面检测代码
    isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
    // 打印状态到控制台
    Debug.Log("Is Grounded: " + isGrounded);
}

如果站在地面时控制台持续输出false,说明地面检测逻辑存在问题,按以下步骤修复;如果输出true但仍无法跳跃,说明跳跃逻辑或控制器参数有冲突。


2. 修复地面检测逻辑

针对Physics.CheckSphere:

  • 调整检测范围:确保groundDistance的值大于角色碰撞体底部与地面的间隙(建议设为0.4~0.6),同时在Scene视图中用Gizmos可视化检测范围:
    void OnDrawGizmosSelected()
    {
        if (groundCheck != null)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(groundCheck.position, groundDistance);
        }
    }
    
    检查红色球体是否覆盖到地面,若未覆盖,调整groundCheck的位置(移到角色碰撞体底部稍下方)或增大groundDistance。
  • 修正LayerMask:避免直接用数字指定层,改用层名称获取遮罩,防止层ID不匹配:
    // 替换原来的LayerMask赋值
    public LayerMask groundMask = LayerMask.GetMask("Ground");
    

针对Physics.Raycast:

  • 确保射线从角色底部向下发射,且长度足够覆盖间隙,同时忽略自身碰撞体:
    isGrounded = Physics.Raycast(groundCheck.position, Vector3.down, groundDistance, groundMask, QueryTriggerInteraction.Ignore);
    
    同样用Gizmos可视化射线:
    void OnDrawGizmosSelected()
    {
        if (groundCheck != null)
        {
            Gizmos.color = Color.blue;
            Gizmos.DrawLine(groundCheck.position, groundCheck.position + Vector3.down * groundDistance);
        }
    }
    

3. 修正跳跃与重力逻辑

不要移除velocity.y += gravity * Time.deltaTime;,这是角色下落的核心逻辑。正确的重力与跳跃处理应该包含贴地时重置y速度,避免角色悬空导致检测失效:

void Update()
{
    isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

    // 贴地时重置y速度,让角色紧贴地面
    if (isGrounded && velocity.y < 0)
    {
        velocity.y = -2f; // 用小的负数而非0,确保角色不会轻微悬空
    }

    // 跳跃逻辑
    if (Input.GetButtonDown("Jump") && isGrounded)
    {
        // 计算跳跃初速度,gravity需为负数(向下)
        velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
    }

    // 应用重力
    velocity.y += gravity * Time.deltaTime;
    // 用CharacterController的Move方法移动,不要直接修改transform.position
    controller.Move(velocity * Time.deltaTime);
}

4. 检查CharacterController参数

  • Skin Width:设为0.08左右,避免碰撞体与地面出现微小间隙导致检测不到。
  • Slope Limit:确保坡度限制合理,若地面有坡度,设置过低会导致角色无法触发地面检测。
  • 不要混用Rigidbody与CharacterController:如果同时挂载了Rigidbody,会破坏CharacterController的碰撞检测,需移除Rigidbody。

5. 检查地面碰撞体设置

  • 确保地面对象的Collider组件已启用,且未勾选Is Trigger。
  • 地面对象的Layer确实设置为Ground,未被误设为其他层。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:10:14