Player getting stuck on colliders (2D)

Hi! After practicing Unity tutorials I am trying to make my first RPG to better learn the engine. I am following this tutorial https://www.youtube.com/watch?v=dbMm2_M3Wfc&list=PLy1Xj-4F5G_cytIH8by-bZ9TVj5qKMlZn&index=4 but find myself with an issue I cannot fix.

Whenever my player walks into a collider, it gets stuck and continues to walk forward over and over again. Any effort to get it to stop or to move away from it go ignored. I’ve tried everything I can think of to fix the issue but am not experienced enough in engine to figure it out on my own and I can’t seem to Google the right phrases/questions to get what I need.

I’ve tried different colliders, I’ve tried enabling interpolate, etc. It does not stop it from sticking.

Here is a video of what I mean.

Here is my PlayerController Script

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

public class PlayerController : MonoBehaviour
{
    public float moveSpeed;
    public bool isMoving;
    public Vector2 input;

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

    private void Update() {
        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("moveX",input.x);
                animator.SetFloat("moveY",input.y);

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

                StartCoroutine(Move(targetPos));
            }
        }

        animator.SetBool("isMoving", isMoving);
    }

    IEnumerator Move(Vector3 targetPos){
        isMoving = true;
    
        while((targetPos - transform.position).sqrMagnitude > Mathf.Epsilon) {
            transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime);
            // var moveVector = new Vector3(input.x , input.y, 0); 
            // body.MovePosition(Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime));
            yield return null;
        }

        transform.position = targetPos;

        isMoving = false;
    }
}

Any and all help or advice would be greatly appreciated.

1 Like

Maybe try to set the collision detection on continuous in the rigidbody of the player
And to prevent the player from sticking make a new material without friction and drag it onto the rigidbody.

I am having the same problem. Tried changing all setting of rigidbody but nothing worked.

Thank you for the suggestion! Unfortunately it did not seem to affect anything.

Wait I watched your linked video and I think its not really beginner friendly. Also if i am seeing this right the player doesn’t have a collider? If that is the case dont go further with this tutorial. For example of you have a scene with a player that has a collider and a wall with a collider they already collide with eachother and you dont need any programming for that. Now he uses functions and stuff. I recommend you watching brackeys they explain things very clear and the right way.

is this a bug or an error on my side? I am using 2022 LTS mac silicon.

the player does have a collider, but i will look into a different tutorial for this part

I decided to make a new Player Controller script with a different code. Something about the tutorial’s code is making it do that - unsure what but it’s not worth the headache. Here’s what I’m using now if you want it. The player still jitters when colliding repeatedly but doesn’t get stuck

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

public class PlayerController : MonoBehaviour
{
   public float movSpeed;
    float speedX, speedY;
    Rigidbody2D rb;
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();  
    }

    // Update is called once per frame
    void Update()
    {
        speedX = Input.GetAxisRaw("Horizontal") * movSpeed;
        speedY = Input.GetAxisRaw("Vertical") * movSpeed;
        rb.velocity = new Vector2(speedX, speedY);
    }
}

Honestly I have no idea, you can maybe try to test in a blank scene where you have a ground and square as the player that will both have a collider and the player a rigidbody and your movement script and compare your game with that scene maybe you will see something. Your movement script looks nice!

Transferred my project to an windows and it worked just fine.

That is the worst playercontroller cript I have seen yet, and I have seen quite a few! I can see that it’s the same thing as the video is doing from jumping through it. I don’t have the time to watch all the way too see if the author has some reason to do things in a weird way, but;

Do not start a coroutine in Update every frame to move you until you hit the target position! That will a) mean that you will get stuck forever if you walk into a wall and b) mean that you get stuck if you press left and then up on the next frame.

The code @sagemdeleon posted is a sensible beginners player controller. It’s a ton simpler, and everything in there is sensible, so go with that.