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

Unity3D玩家Rigidbody开重力仍可飞,求修复及跳跃、墙跑功能实现方法

Unity 3D玩家飞行异常排查及跳跃、墙跑功能实现方案

玩家可飞行异常排查

  • 检查Rigidbody组件的*重力缩放(Gravity Scale)*参数是否设置为0或者过小,即使勾选了重力开关,缩放为0也不会受重力影响
  • 检查玩家身上的碰撞体是否勾选了Is Trigger,触发型碰撞体不会产生物理碰撞,玩家会和地面无碰撞交互
  • 检查当前场景中是否存在其他持续给玩家刚体施加向上力的脚本,避免多脚本逻辑冲突
  • 检查地面碰撞体的Layer是否被排除在Raycast检测之外,你当前的接地检测没有指定Layer过滤,如果射线误检测到空中的非地面对象,会导致逻辑误判玩家处于接地状态,建议给地面单独设置Layer,给Physics.Raycast增加Layer参数过滤检测对象
  • 检查Rigidbody的*阻力(Drag)*参数是否设置过大,过大的垂直阻力会抵消重力效果,导致下落速度极慢看起来像飞行
  • 检查玩家胶囊碰撞体是否和其他碰撞体产生了持续的挤压碰撞,导致刚体被持续向上弹开

跳跃功能实现

首先在代码中新增如下变量:

public float jumpForce = 7f;
public float airMultiplier = 0.4f; // 空中移动阻力系数,避免空中移动和地面一样灵活

修改MyInput方法,新增跳跃输入检测逻辑:

void MyInput()
{
    horizontalMovement = Input.GetAxisRaw("Horizontal");
    verticalMovement = Input.GetAxisRaw("Vertical");

    moveDirection = transform.forward * verticalMovement + transform.right * horizontalMovement;

    // 跳跃输入判定
    if(Input.GetKeyDown(KeyCode.Space) && isGrounded)
    {
        // 重置垂直速度避免跳跃高度和下落速度挂钩
        rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
        rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    }
}

修改MovePlayer方法,区分地面和空中的移动力度:

void MovePlayer()
{
    float currentSpeedMultiplier = isGrounded ? 1f : airMultiplier;
    rb.AddForce(moveDirection.normalized * moveSpeed * currentSpeedMultiplier, ForceMode.Acceleration);
}

墙跑功能实现

首先做前置配置:给场景中所有可墙跑的墙面单独设置Wall层级。
在代码中新增如下变量:

public float wallRunForce = 8f;
public float maxWallRunTime = 2f;
public float wallCheckDistance = 0.7f;
private float wallRunTimer;
private bool isWallLeft;
private bool isWallRight;
private bool isWallRunning;
public LayerMask wallLayer; //  inspector中选择刚才创建的Wall层

修改Update方法,新增墙面检测和墙跑状态判定逻辑:

private void Update()
{
    isGrounded = Physics.Raycast(transform.position, Vector3.down, playerHeight / 2 + 0.01f);
    // 左右墙面检测
    isWallRight = Physics.Raycast(transform.position, transform.right, wallCheckDistance, wallLayer);
    isWallLeft = Physics.Raycast(transform.position, -transform.right, wallCheckDistance, wallLayer);

    // 墙跑生效判定:不在地面、挨着墙面、玩家按下前向移动键
    if((isWallLeft || isWallRight) && !isGrounded && verticalMovement > 0)
    {
        if(wallRunTimer <= 0) wallRunTimer = maxWallRunTime;
        isWallRunning = true;
        wallRunTimer -= Time.deltaTime;
        // 墙跑期间禁用重力避免下落
        rb.useGravity = false;
        rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
    }
    else
    {
        isWallRunning = false;
        rb.useGravity = true;
        // 墙跑计时器离开墙面后自动恢复
        if(wallRunTimer < maxWallRunTime) wallRunTimer += Time.deltaTime * 0.5f;
    }

    print(isGrounded);
    MyInput();
}

修改FixedUpdate方法,新增墙跑驱动力逻辑:

private void FixedUpdate()
{
    MovePlayer();
    if(isWallRunning)
    {
        rb.AddForce(transform.forward * wallRunForce, ForceMode.Acceleration);
        // 可选:添加贴墙的力,避免玩家移动过程中脱离墙面
        if(isWallRight) rb.AddForce(-transform.right * 2f, ForceMode.Acceleration);
        if(isWallLeft) rb.AddForce(transform.right * 2f, ForceMode.Acceleration);
    }
}

如果需要增加墙跳功能,只需要在MyInput的跳跃判定逻辑中,增加墙跑状态下的分支,给玩家施加朝向墙面外侧+向上的冲量即可。

内容的提问来源于stack exchange,提问作者canadian.goose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:30:04