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

Unity 2D角色未按键自动向上移动如何解决?怎样自定义二段跳功能?

问题修复方案

1. 异常原因说明

  • 自动向上移动的核心问题:Jump()方法中if (Input.GetKeyDown(KeyCode.Space));末尾多了一个分号,直接终止了条件判断的作用域,后续给Rigidbody赋值向上速度的代码每帧都会执行,所以即使不按按键角色也会持续上移。
  • 跳跃控制失效的其他问题:
    1. 同时使用transform.Translate和Rigidbody2D控制位移,会和物理引擎计算冲突,导致碰撞检测、重力效果异常
    2. 缺少地面检测逻辑,无法限制空中跳跃的次数
    3. 物理属性修改没有放在FixedUpdate中执行,会出现帧率相关的位移异常

2. 基础跳跃功能修复代码

public class Movement : MonoBehaviour {
    public float speed = 10f;
    public float jumpSpeed = 7f;
    // 地面层,需要在Inspector中选中你场景里对应地面的Layer
    public LayerMask groundLayer;
    // 地面检测点,一般放在角色脚底
    public Transform groundCheckPoint;
    public float groundCheckRadius = 0.2f;

    private Rigidbody2D rb;
    private float inputX;

    void Start() {
        rb = GetComponent<Rigidbody2D>();
    }

    // 输入检测放在Update执行,避免漏判按键
    void Update() {
        inputX = Input.GetAxis("Horizontal");
        // 角色翻转逻辑
        if (inputX < 0) {
            transform.localScale = new Vector3(5, transform.localScale.y, transform.localScale.z);
        }
        if (inputX > 0) {
            transform.localScale = new Vector3(-5, transform.localScale.y, transform.localScale.z);
        }

        JumpCheck();
    }

    // 物理修改放在FixedUpdate执行,符合Unity物理更新周期
    private void FixedUpdate() {
        // 用Rigidbody控制水平位移,保留y轴的重力/跳跃速度
        rb.velocity = new Vector2(inputX * speed, rb.velocity.y);
    }

    // 判断是否触地
    private bool IsGrounded() {
        return Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, groundLayer);
    }

    private void JumpCheck() {
        // 删掉了多余的分号,增加触地判断
        if (Input.GetKeyDown(KeyCode.Space) && IsGrounded()) {
            rb.velocity = new Vector2(rb.velocity.x, jumpSpeed);
        }
    }
}

使用注意:需要在场景中给角色加一个空物体作为groundCheckPoint,拖到角色脚底位置,然后在Inspector中选择对应的地面Layer即可。

3. 二段跳/多段跳实现方案

只需要在基础代码上增加跳跃次数计数即可,修改后的完整代码如下:

public class Movement : MonoBehaviour {
    public float speed = 10f;
    public float jumpSpeed = 7f;
    public LayerMask groundLayer;
    public Transform groundCheckPoint;
    public float groundCheckRadius = 0.2f;
    // 最大跳跃次数,2就是二段跳,3就是三段跳,可自定义
    public int maxJumpCount = 2;

    private Rigidbody2D rb;
    private float inputX;
    private int currentJumpCount;

    void Start() {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update() {
        inputX = Input.GetAxis("Horizontal");
        if (inputX < 0) {
            transform.localScale = new Vector3(5, transform.localScale.y, transform.localScale.z);
        }
        if (inputX > 0) {
            transform.localScale = new Vector3(-5, transform.localScale.y, transform.localScale.z);
        }

        JumpCheck();
        // 触地时重置跳跃次数
        if (IsGrounded()) {
            currentJumpCount = maxJumpCount;
        }
    }

    private void FixedUpdate() {
        rb.velocity = new Vector2(inputX * speed, rb.velocity.y);
    }

    private bool IsGrounded() {
        return Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, groundLayer);
    }

    private void JumpCheck() {
        if (Input.GetKeyDown(KeyCode.Space) && currentJumpCount > 0) {
            rb.velocity = new Vector2(rb.velocity.x, jumpSpeed);
            currentJumpCount--;
        }
    }
}

如果需要自定义跳跃高度、空中移速、跳跃下落加速度等效果,只需要对应修改jumpSpeed、speed,或者在跳跃时根据当前跳跃次数调整jumpSpeed的数值即可。

内容的提问来源于stack exchange,提问作者Sultan ul Arefin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:06:01