Search code examples
unity-game-engine2d-gamescollider

Unity 2D collider is not behaving properly. I cant move through/on the one block below the 2D collider


So I was trying to make a tile base movement and suddenly came encountered this problem with collider2D. So I set up a tile size 2D collider for that pole there in the image but then there's one problem. I suddenly noticed that I cannot move through or on the one tile/block below the 2D Collider.

Note that the character don't have any collider 2d or rigidbody 2d. The character is relying on function private bool notBlocked(Vector3 movePosition) to stop my character from moving and stop animation when blocked.

I highlighted the block/tile where I can't move. There's no collider there so I don't know why my character can't walk through/on it Cant move on this block "Highlighted Red"

but then when I try it on the block on the top of the collider, it works same as the left and right tile/block around the collider.

Can move to the block in top of every collider

So this is the code I used for movement and stop movement when colliding.

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

public class PlayerController : MonoBehaviour
{
    private float moveSpeed;
    public LayerMask SolidObjectLayer;

    private bool isMoving;
    private Vector2 input;
    private Animator animator;

    private void Update()
    {
        InputMove();
    }

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void InputMove()
    {
        if (!isMoving)
        {

            input.x = Input.GetAxisRaw("Horizontal");
            input.y = Input.GetAxisRaw("Vertical");

            if (input.x != 0) input.y = 0;

            if (input != Vector2.zero)
            {
                animator.SetFloat("Horizontal", input.x);
                animator.SetFloat("Vertical", input.y);

                var movePos = transform.position;
                movePos.x += input.x;
                movePos.y += input.y;

                if (notBlocked(movePos))
                    StartCoroutine(Move(movePos));
            }
        }

        if (Input.GetKey(KeyCode.LeftShift))
        {
            moveSpeed = 6f;
            animator.speed = 1.5f;
        }

        else
        {
            moveSpeed = 4f;
            animator.speed = 1f;
        }
        animator.SetBool("isMoving", isMoving);
    }

    IEnumerator Move(Vector3 movePos)
    {
        isMoving = true;
        while((movePos - transform.position).sqrMagnitude > Mathf.Epsilon)
        {
            transform.position = Vector3.MoveTowards(transform.position, movePos, moveSpeed * Time.deltaTime);
            yield return null;
        }
        transform.position = movePos;
        isMoving = false;
    }

    private bool notBlocked(Vector3 movePosition)
    {
        if(Physics2D.OverlapCircle(movePosition, 0.2f, SolidObjectLayer) != null)
        {
            return false;
        }

        return true;
    }
}

I don't know if It has something to do with "private bool isBlocked()", but it's the function that I used to stop the character from moving any further if being block.


Solution

  • Okay so I somehow manage to figure out how to fix it. So the character can only move on block that has no collider enter image description here

    So It means that if that yellow point is going straight through a collider then it will prevent my character from moving. So it seems like the OverlapCircle cast from the center of the character or the pivot so I changed the pivot of my character a little bit lower.

    So as you can see here the problem is the OverLapCircle is trying to walk in the collider but then the script is preventing it from happening and preventing me from moving on the time below the tile. enter image description here