Unity 2D平台游戏下蹲问题:角色蹲伏时穿模掉落出地图
Unity 2D角色蹲伏穿模问题解决
问题场景
开发2D平台游戏时,长按下蹲键(1秒内)角色会穿过地面掉落出地图,尝试过教程和重写脚本都没解决,需要实现蹲伏时不穿模的效果。
问题根源
- 碰撞体偏移量在
Update里被重复赋值覆盖,蹲伏时没正确调整碰撞体位置 - 蹲伏只改了碰撞体大小,没同步改偏移,导致碰撞体位置和角色模型不匹配,触发穿模
- 部分Sprite变量没初始化,可能引发额外异常
修复后的完整代码
using UnityEngine; public class PlayerMovement : MonoBehaviour { private Rigidbody2D rb; private Animator anim; private SpriteRenderer sprite; private int jumpCount = 0; private int maxJumps = 2; private bool grounded = false; private float dirX; private new BoxCollider2D collider; // 直接在Inspector面板拖入对应的Sprite public Sprite crouchingSprite; public Sprite standingSprite; private Vector2 crouchingSize = new Vector2(1, 0.5f); private Vector2 crouchingOffset = new Vector2(0, -0.25f); private Vector2 standingSize = new Vector2(1, 1); private Vector2 standingOffset = Vector2.zero; private void Start() { rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); sprite = GetComponent<SpriteRenderer>(); collider = GetComponent<BoxCollider2D>(); // 初始化默认显示站立Sprite if(standingSprite != null) sprite.sprite = standingSprite; } private void Update() { dirX = Input.GetAxisRaw("Horizontal"); rb.velocity = new Vector3(dirX * 7f, rb.velocity.y, 0); // 跳跃与二段跳逻辑 if (Input.GetButtonDown("Jump") && jumpCount < maxJumps) { rb.velocity = new Vector3(rb.velocity.x, 14f, 0); grounded = false; jumpCount++; } if (grounded) { jumpCount = 0; } // 蹲伏输入处理 if (Input.GetButtonDown("Crouch")) { if(crouchingSprite != null) sprite.sprite = crouchingSprite; collider.size = crouchingSize; collider.offset = crouchingOffset; } if (Input.GetButtonUp("Crouch")) { if(standingSprite != null) sprite.sprite = standingSprite; collider.size = standingSize; collider.offset = standingOffset; } UpdateAnimationState(); } private void UpdateAnimationState() { dirX = Input.GetAxisRaw("Horizontal"); anim.SetBool("running", dirX != 0); if (dirX > 0f) { sprite.flipX = false; } else if (dirX < 0f) { sprite.flipX = true; } } private void OnCollisionEnter2D(Collision2D other) { if (other.gameObject.CompareTag("Ground")) { grounded = true; jumpCount = 0; // 落地重置跳跃次数,逻辑更合理 } } private void OnCollisionExit2D(Collision2D other) { if (other.gameObject.CompareTag("Ground")) { grounded = false; } } }
关键修改说明
- 碰撞体偏移修复:把碰撞体的大小、偏移改成类成员变量,不在
Update里重复赋值,蹲伏时同时设置collider.offset,让碰撞体跟着角色模型下移,保证和地面的碰撞检测正常 - Sprite变量优化:把蹲伏、站立Sprite改成公开变量,直接在Unity编辑器拖入,还加了空值判断,避免空引用报错
- 地面碰撞逻辑完善:新增
OnCollisionExit2D,离开地面时更新grounded状态;落地时把jumpCount设为0,跳跃逻辑更严谨 - 动画代码简化:跑步状态判断直接用
dirX != 0,减少冗余代码
内容的提问来源于stack exchange,提问作者Magatsu
相关产品推荐
相关产品推荐

