Lavender Vampire
Lavender Vampire

Reputation: 21

My player is getting stuck inside the wall in the 2D platforming game I am making in unity

I am making a 2D platforming game in unity. For some reason, the player is getting stuck in the wall. I have used a Tilemap for the wall, then used tilemap Collider 2D with composite collider. The same thing works fine with the ground.

When I go left facing the wall, it behaves as expected: enter image description here

When I release the left arrow button, it also shows the expected result: enter image description here

But when I click right arrow next, the player gets stuck inside the wall: enter image description here

and cannot get out: enter image description here

Here is my player movement code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerScript : MonoBehaviour
{
    // Start is called before the first frame update
    
    [SerializeField] private float movement_speed = 2;
    [SerializeField] private float jump_power = 5;
    [SerializeField] private LayerMask groundLayer;
    [SerializeField] private LayerMask wallLayer;

    private Rigidbody2D rb_player;
    private BoxCollider2D boxCollider;
    private Animator anim;

    private void Start()
    {
        
    }

    private void Awake()
    {
        rb_player = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        boxCollider = GetComponent<BoxCollider2D>();
        groundLayer = LayerMask.GetMask("ground");
        wallLayer = LayerMask.GetMask("wall");
    }

    // Update is called once per frame
    private void Update()
    {
        float x = Input.GetAxis("Horizontal");

        
        rb_player.velocity = new Vector2(x * movement_speed, rb_player.velocity.y);
        

        //flip the player
        if(x > 0.01f)
        {
            transform.localScale = new Vector3(1, 1, 1);
        }

        else if(x < -0.01f)
        {
            transform.localScale = new Vector3(-1, 1, 1);
        }


        if(Input.GetKeyDown(KeyCode.Space) && isGrounded())
        {
            jump();
        }


        anim.SetBool("run", x != 0);

        anim.SetBool("jump", !isGrounded());


        print("wall: "+isTouchingWall());
        print("ground: "+isGrounded());
        
    }


    private void jump()
    {
        rb_player.velocity = new Vector2(rb_player.velocity.x, jump_power);
        anim.SetTrigger("jump_trigger");
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        // if(collision.gameObject.tag == "ground")
        // {
        //     grounded = true;
        // }
    }

    private bool isGrounded()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, Vector2.down, .2f, groundLayer);
        return raycastHit.collider != null;
    }


    private bool isTouchingWall()
    {
        RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, new Vector2(transform.localScale.x,0), .1f, wallLayer);
        return raycastHit.collider != null;
    }
}

It would be nice if anyone can help me as I am a complete beginner in game development with unity.

Upvotes: 0

Views: 403

Answers (1)

Jukoz
Jukoz

Reputation: 117

The problem

Your pivot point of your player (where your player script is attached) isn't centered like your collider. Because of this, your box collider is being flipped like a page from a book and it lands inside the wall.

To fix it

Make sure that your player pivot point is the same as the center of your BoxCollider2D. This way, your collider won't "teleport" from right to left and bypass walls.

Other tips

I see some beginner's mistakes in your code, so even if you manage to fix your issue, I highly recommend to follow the next tips:

  • All physic based code (jump, movement, etc.) should go inside FixedUpdate() method and use Time.deltaTime or Time.fixedDeltaTime to keep the same speed (for movement and jump) among computers.
  • Use the proper naming conventions, your variables should be camel case, no underscores. Methods (and Classes) should always start with a capital letter in C# (PascalCase).

Hopefully this will help you.

Upvotes: 1

Related Questions