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; } }
关键改动说明
- 将停止水平速度的逻辑移至
FixedUpdate,每帧检查条件,确保只要满足“地面+无移动键”就立即停止。 - 移除
OnCollisionEnter2D中的停止代码,避免仅在接触地面瞬间触发的问题。 - 补充
OnCollisionExit2D方法,确保角色离开地面时grounded状态正确更新,防止逻辑出错。
内容的提问来源于stack exchange,提问作者France Josh Fetalvero
相关产品推荐
相关产品推荐

