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

Unity中如何实现玩家仅在地面跳跃、空中不可跳跃

解决玩家仅能在地面跳跃的问题

你的代码目前没有判断玩家是否处于地面,所以只要按空格就会触发跳跃。以下是两种可靠的实现方式,选一种适合你的场景即可:

方法1:射线检测(推荐,精准可控)

通过从玩家模型底部向下发射短射线,检测是否触碰到地面:

using UnityEngine;

public class Player : MonoBehaviour
{
    private bool jumpKeyWasPressed;
    private float horizontalInput;
    private Rigidbody rigidbodyComponent;
    // 射线检测的长度,根据玩家模型高度调整
    [SerializeField] private float groundCheckDistance = 0.1f;
    // 指定地面所在的图层,避免误判其他物体
    [SerializeField] private LayerMask groundLayer;

    void Start()
    {
        rigidbodyComponent = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpKeyWasPressed = true;
        }
        horizontalInput = Input.GetAxis("Horizontal");
    }

    private void FixedUpdate()
    {
        // 检测是否在地面:从玩家位置向下发射射线
        bool isGrounded = Physics.Raycast(transform.position, Vector3.down, groundCheckDistance, groundLayer);
        
        if (jumpKeyWasPressed && isGrounded)
        {
            rigidbodyComponent.AddForce(Vector3.up * 5, ForceMode.VelocityChange);
            jumpKeyWasPressed = false;
        }
        
        rigidbodyComponent.velocity = new Vector3(horizontalInput, rigidbodyComponent.velocity.y, 0);
    }
}

配置说明:

  • 在Unity编辑器中,给你的地面物体设置单独的图层(比如命名为Ground)
  • 把脚本中的groundLayer字段选中Ground图层
  • 根据玩家模型的高度调整groundCheckDistance,确保射线刚好能触碰到地面,不会太长导致穿透地面

方法2:碰撞器检测(适合简单场景)

通过碰撞事件判断玩家是否接触地面:

using UnityEngine;

public class Player : MonoBehaviour
{
    private bool jumpKeyWasPressed;
    private float horizontalInput;
    private Rigidbody rigidbodyComponent;
    private bool isGrounded;

    void Start()
    {
        rigidbodyComponent = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpKeyWasPressed = true;
        }
        horizontalInput = Input.GetAxis("Horizontal");
    }

    private void FixedUpdate()
    {
        if (jumpKeyWasPressed && isGrounded)
        {
            rigidbodyComponent.AddForce(Vector3.up * 5, ForceMode.VelocityChange);
            jumpKeyWasPressed = false;
        }
        
        rigidbodyComponent.velocity = new Vector3(horizontalInput, rigidbodyComponent.velocity.y, 0);
    }

    // 当玩家碰撞器接触到其他物体时触发
    private void OnCollisionStay(Collision collision)
    {
        // 判断接触的物体是否是地面(可以用标签或图层)
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }

    // 当玩家碰撞器离开物体时触发
    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = false;
        }
    }
}

配置说明:

  • 给地面物体添加Ground标签
  • 确保玩家和地面都有碰撞器(玩家用CapsuleCollider,地面用BoxCollider等),且至少有一个物体有Rigidbody(地面可以设为静态)

之前你添加isGrounded没效果,大概率是检测逻辑有问题——比如射线长度不对、没指定图层,或者碰撞事件的判断条件错误。按上面的配置步骤操作就能解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:37:12