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

Unity中isGrounded检测异常导致二段跳、跳跃表现不稳定问题求助

核心问题原因
  • isGrounded检测逻辑缺陷:仅通过OnCollisionStay设置isGrounded = true,未在离开碰撞体时重置状态,且只要碰到任意碰撞体(包括墙面、障碍物侧面)都会判定为接地,直接导致空中可触发二段跳的问题。
  • 移动逻辑不符合物理规范:直接调用transform.Translate移动刚体,会绕过Unity物理引擎的位置计算,导致碰撞检测同步延迟、物理状态异常,是跳跃高度不稳定、碰撞判定不准的核心原因。
  • 刚体旋转未做限制:物理碰撞会给立方体施加扭矩产生旋转,你之前尝试用AddForce移动时出现旋转,就是因为没有锁定刚体的旋转轴。
  • 移动参数逻辑错误:原有代码中movement/speed写法错误,会导致speed数值越大移动速度越慢,和预期逻辑相反。
修复步骤
  1. 选中挂载该脚本的立方体对象,在Inspector面板找到Rigidbody组件,展开「Constraints」选项,勾选Freeze Rotation下的X、Y、Z三个复选框,完全禁止立方体受物理扭矩影响产生旋转。
  2. 替换isGrounded检测逻辑为脚底射线检测,可精准判定是否接触地面,避免墙面等侧面碰撞误判为接地。
  3. 替换transform.Translate移动逻辑为直接修改刚体的水平速度,保留Y轴的重力/跳跃速度,既保证移动平滑不卡顿,也不会干扰物理碰撞检测。
  4. 修正移动速度计算逻辑,调整跳跃参数保证手感一致。
修复后完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
 
public class PlayerController : MonoBehaviour
{
    private Rigidbody rb;
    public float jumpForce = 400f;
    public bool isGrounded;
    // 移动速度可直接在Inspector调整
    public float speed = 5f;
    private float movementX;
    private float movementY;
    // 射线检测长度,可根据立方体实际高度调整,比立方体半高多0.05-0.1即可
    public float groundCheckLength = 0.55f;
    // 可选:指定只检测地面层,避免和其他物体碰撞误判,需要在Unity里先建Ground层
    public LayerMask groundLayer;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        // 代码锁旋转,和Inspector勾选效果一致
        rb.freezeRotation = true;
    }
 
    void OnMove(InputValue movementValue)
    {
        Vector2 movementVector = movementValue.Get<Vector2>();
        movementX = movementVector.x;
        movementY = movementVector.y;
    }
 
    private void Update()
    {
        // 每帧做接地检测,从立方体中心向下发射射线
        isGrounded = Physics.Raycast(transform.position, Vector3.down, groundCheckLength, groundLayer);

        if (Keyboard.current.spaceKey.wasPressedThisFrame && isGrounded)
        {
            // 清空Y轴速度再施加跳跃力,避免落地时残留速度导致跳跃高度不稳定
            rb.velocity = new Vector3(rb.velocity.x, 0, rb.velocity.z);
            rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
            Debug.Log("Jump triggered");
        }
    }
 
    private void FixedUpdate()
    {
        // 只修改水平方向速度,保留Y轴的重力/跳跃速度
        Vector3 movement = new Vector3(movementX * speed, rb.velocity.y, movementY * speed);
        rb.velocity = movement;
    }
}
补充说明

如果不想用射线检测,也可以修改碰撞检测逻辑,判断碰撞法线是否向上来避免墙面误判:

private void OnCollisionStay(Collision collision)
{
    // 检查碰撞面法线是否接近向上,误差范围可调整
    foreach (ContactPoint contact in collision.contacts)
    {
        if (Vector3.Dot(contact.normal, Vector3.up) > 0.7f)
        {
            isGrounded = true;
            break;
        }
    }
}

private void OnCollisionExit(Collision collision)
{
    isGrounded = false;
}

内容的提问来源于stack exchange,提问作者Coder Gautam YT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:54:02