Search code examples
unity-game-enginephysics-engine

Unity 2D Platformer: Crouching issues


I am having an issue currently with my C# Script for my 2D PLatformer made in Unity. My issue is that when I press the crouch button for long enough(a second or less), my character falls through the floor and out of the map. I am stumped on how to get the sprite to not do that.

Thank you for the help! Code is posted below! (I posted the entire script for more clarification, however the issue is within the if statements regarding the "Crouch" input.)

For crouching, I have tried everything, I searched some tutorials, some in which I tried rewriting my entire script, but it got me no closer than I am now. For this I am expecting the sprite to not phase through the ground while crouching. There is not too many results with people asking about crouching in a 2d platformer.

using System.Collections;
using System.Collections.Generic;
using System.IO;
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;
    private Sprite crouching;
    private Sprite standing;
    private Vector2 crouchingSize;
    private Vector2 standingSize;
    private Vector2 crouchingOffset;


    // Start is called before the first frame update
    private void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        sprite = GetComponent<SpriteRenderer>();
        collider = GetComponent<BoxCollider2D>();

    }

    // Update is called once per frame
    private void Update()
    {
        dirX = Input.GetAxisRaw("Horizontal");
        float dirY = Input.GetAxisRaw("Vertical");
        rb.velocity = new Vector3(dirX * 7f, rb.velocity.y, 0);

        //Jump Button and double jump
        if (Input.GetButtonDown("Jump") && jumpCount < maxJumps)
        {
            rb.velocity = new Vector3(rb.velocity.x, 14f, 0);
            grounded = false;
            jumpCount = jumpCount + 1;
        }

        if (grounded == true)
        {
            jumpCount = 0;
        }

        crouchingSize = new Vector2(1, 0.5f);
        crouchingOffset = new Vector2(0, -0.25f);
        standingSize = new Vector2(1, 1);
        crouchingOffset = Vector2.zero;

        //Start crouch
        if (Input.GetButtonDown("Crouch"))
        {
            sprite.sprite = crouching;
            collider.size = crouchingSize;
        }

            //Stop crouch
            if (Input.GetButtonUp("Crouch"))
            {
                sprite.sprite = standing;
                collider.size = standingSize;

            }

            UpdateAnimationState();
    }

    private void UpdateAnimationState()
    {
        dirX = Input.GetAxisRaw("Horizontal");

        if (dirX > 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = false;
        }
        else if (dirX < 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = true;
        }
        else
        {
            anim.SetBool("running", false);
        }
    }

    private void OnCollisionEnter2D(Collision2D collider)
    {
        if (collider.gameObject.tag == "Ground")
        {
            jumpCount = maxJumps;
            grounded = true;
        }
    }

}

EDIT: Code block has been edited to reflect the solution to my question.


Solution

  • You seem to be transforming your player and then adding force to it's rigid body, which might cause clipping if the force factor is too big. What kind of 2D game are you trying to implement? In 2D you'd usually just want to scale down the collider object and change the sprite to a crouching one.

    public sprite crouching;
    public sprite standing;
    public vector2 crouchingSize;
    public vector2 standingSize;
    .........
    ......
    ....
    private void Update() 
    {
            if (Input.GetButtonDown("Crouch"))
            {
                SpriteRenderer.sprite = crouching;
                Collider.size = crouchingSize;
            }
            //Stop crouch
            if (Input.GetButtonUp("Crouch"))
            {
                SpriteRenderer.sprite = standing
                Collider.size = standingSize;
            }
    }