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

Unity 2D平台游戏下蹲问题:角色蹲伏时穿模掉落出地图

Unity 2D角色蹲伏穿模问题解决

问题场景

开发2D平台游戏时,长按下蹲键(1秒内)角色会穿过地面掉落出地图,尝试过教程和重写脚本都没解决,需要实现蹲伏时不穿模的效果。

问题根源

  1. 碰撞体偏移量在Update里被重复赋值覆盖,蹲伏时没正确调整碰撞体位置
  2. 蹲伏只改了碰撞体大小,没同步改偏移,导致碰撞体位置和角色模型不匹配,触发穿模
  3. 部分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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:03:09