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

Unity 2D角色地面静止需求:未按移动键时立即停止速度

问题解决:2D角色地面静止时立即停止水平速度

需求:角色正常移动,未按下任何移动键且处于地面时,立即停止水平速度。原代码用&&组合条件未达到预期效果。

原代码

public class Movement : MonoBehaviour
{
    public Rigidbody2D rb;

    public float moveSpeed = 2000f;
    public float jumpSpeed = 20f;
    private bool grounded;

    private void FixedUpdate ( )
    {
        if ( Input.GetKey ( "d" ) )
        {
            rb.AddForce ( new Vector2 ( moveSpeed, 0f ) * Time.deltaTime );
            Debug.Log ( "d" );
        }

        if ( Input.GetKey ( "a" ) )
        {
            rb.AddForce ( new Vector2 ( -moveSpeed, 0f ) * Time.deltaTime );
            Debug.Log ( "a" );
        }

        if ( Input.GetKey ( "w" ) && grounded )
        {
            //rb.AddForce(new Vector2(rb.velocity.x, jumpSpeed));
            Jump ( );
            Debug.Log ( "w" );
        }
    }

    private void Jump ( )
    {
        rb.velocity = new Vector2 ( rb.velocity.x, jumpSpeed );
        grounded = false;
    }

    private void OnCollisionEnter2D ( Collision2D collision )
    {
        if ( collision.gameObject.tag == "ground" )
            grounded = true;
        if ( Input.GetKey ( "d" ) == false && Input.GetKey ( "a" ) == false && collision.gameObject.tag == "ground" )
        {
            rb.velocity = new Vector2 ( 0, rb.velocity.y );
            Debug.Log ( "stopped" );
        }
    }
}

问题分析

原代码的停止逻辑写在OnCollisionEnter2D中,只有角色刚接触地面时才会触发停止,但实际需要的是:只要角色在地面且没有按下移动键,就持续保持水平速度为0。这个逻辑应该放在处理物理帧的FixedUpdate中,每帧检查条件并生效。

修改后的代码

public class Movement : MonoBehaviour
{
    public Rigidbody2D rb;

    public float moveSpeed = 2000f;
    public float jumpSpeed = 20f;
    private bool grounded;

    private void FixedUpdate ( )
    {
        // 处理移动输入
        if ( Input.GetKey ( "d" ) )
        {
            rb.AddForce ( new Vector2 ( moveSpeed, 0f ) * Time.deltaTime );
            Debug.Log ( "d" );
        }

        if ( Input.GetKey ( "a" ) )
        {
            rb.AddForce ( new Vector2 ( -moveSpeed, 0f ) * Time.deltaTime );
            Debug.Log ( "a" );
        }

        // 处理跳跃
        if ( Input.GetKey ( "w" ) && grounded )
        {
            Jump ( );
            Debug.Log ( "w" );
        }

        // 核心:地面静止时停止水平速度
        if ( grounded && !Input.GetKey("a") && !Input.GetKey("d") )
        {
            rb.velocity = new Vector2(0, rb.velocity.y);
            Debug.Log("stopped");
        }
    }

    private void Jump ( )
    {
        rb.velocity = new Vector2 ( rb.velocity.x, jumpSpeed );
        grounded = false;
    }

    private void OnCollisionEnter2D ( Collision2D collision )
    {
        if ( collision.gameObject.tag == "ground" )
            grounded = true;
        // 删除原停止逻辑,改为在FixedUpdate中处理
    }

    // 补充:离开地面时更新grounded状态(避免角色卡在地面判定外)
    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "ground")
            grounded = false;
    }
}

关键改动说明

  1. 将停止水平速度的逻辑移至FixedUpdate,每帧检查条件,确保只要满足“地面+无移动键”就立即停止。
  2. 移除OnCollisionEnter2D中的停止代码,避免仅在接触地面瞬间触发的问题。
  3. 补充OnCollisionExit2D方法,确保角色离开地面时grounded状态正确更新,防止逻辑出错。

内容的提问来源于stack exchange,提问作者France Josh Fetalvero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:15:41