2D Platformer Movement Problem. Randomly stops moving at certain spots.

Background info:
So pretty much I started development for a 2D platformer. I have recently (kinda) finnished the first enemy, coding wise. I have a scene set up which is just a basic 11x1 platform for the enemy and player to movearound on. The player moves around just fine, but when the enemy is added something weird happens. Randomly during the runtime the enemy will get stuck at a certain position (Generally near the edge, but not always) and then it for some reason at certain positions it also stops the player from moving past.

For example:

[ 1 ][ 2 ][ 3 ][ 4 ][ 5][ 6 ][ 7 ][ 8 ][ 9 ][ 10 ][ 11 ]

If the enemy randomly got stuck at point 2, the player might get stuck at point 9 when moving right even though the player can still walk over point 9 when walking to the left.

To my knowledge, It’s completly random when / where they get stuck. I know this has something to do with the enemy because when the enemy isn’t active in the scene, the player can move fine.

Enemy Code:
using UnityEngine;
using System.Collections;

public class Icey : MonoBehaviour {

    // Enemy Description:
    // Name - Icey.
    // Walks around at speed 2, but when the player is seen
    // He charges at speed 5. If the player moves out of sight
    // Icey won't stop charging straight away.
    // When he collides with the player, Icey spawns a iceberg
    // (Just for visual effects) which kills the player.
    // If Icey goes near a drop / cliff,
    // He automaticly turns around.


    // Refrences
    private Transform thisEnemy; // Refers to the transform of this enemy
    private Rigidbody2D rb; // The attached rigidbody to Icey.
    public GameObject Iceberg; // The object that spawns when Icey collides with player.
    public Transform gp_Left; // The left ground point. Detects when near edge of ground.
    public Transform gp_Right; // The right ground point. Detects when near edge of ground.

    // Vars
    private int faceDir; // The dirrection Icey is facing. -1 = Left. 1 = Right.
    public float defaultFaceDirCooldown; // Helps when reseting the dirFaceCooldown.
    private float faceDirCooldown; // When turning around, stops from changing dir every frame.
    public int moveSpeed; // The current speed;
    public int defaultSpeed; // The default speed;
    public int chargeSpeed; // The speed when Icey charges the player.
    public float defaultChargeStopCooldown; // Helps when reseting the ChargeStopCooldown.
    private float chargeStopCooldown; // The time it takes before Icey stops charging after the player is    out of sight.
    public float gp_Radius; // The collision radius for each ground point.
    public LayerMask groundMask; // Helps detects which objects are ground objects.
    private bool leftGroundSafe; // Set to true if Icey can continue moving left.
    private bool rightGroundSafe; // Set to true if Icey can continue moving righ.
    private float thisEnemy_Ycentered; // The coords of the vertical center of Icey because the pivot is set to the bottom.

    // Use this for initialization
    void Start () {
        thisEnemy = this.gameObject.transform;
        thisEnemy_Ycentered = thisEnemy.position.y;
        thisEnemy_Ycentered += 0.5f;
        rb = GetComponent<Rigidbody2D>();
        moveSpeed = defaultSpeed;
        faceDir = -1;
        faceDirCooldown = defaultFaceDirCooldown;
        chargeStopCooldown = defaultChargeStopCooldown;
    }
	
	// Update is called once per frame
	void Update () {
        Debug.DrawRay(new Vector2(thisEnemy.position.x, thisEnemy_Ycentered), new Vector2(faceDir*10, 0), Color.green);
        // Timers //
        faceDirCooldown -= Time.deltaTime;

        // turnAround function call
        leftGroundSafe = Physics2D.OverlapCircle(gp_Left.position, gp_Radius, groundMask); // Detects if the ground points are colliding with ground on the left side of Icey.
        rightGroundSafe = Physics2D.OverlapCircle(gp_Right.position, gp_Radius, groundMask); // Detects if the ground points are colliding with ground on the right side of Icey.
        if (!leftGroundSafe || !rightGroundSafe)
        {
            if (faceDirCooldown <= 0)
            {
                faceDirCooldown = defaultFaceDirCooldown; // resets the cooldown timer.
                rb.velocity = Vector2.zero; // Temporary stops all of Icey's movement
                faceDir = -faceDir; // Inverses the faceDir.
                transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y);
            }
        }

        // Movement
        Vector2 moveDir = new Vector2(faceDir * moveSpeed, rb.velocity.y);
        rb.velocity = moveDir;
    }

    // Used for detecting collisions.
    void OnCollisionEnter2D(Collision2D other) {
        if (other.gameObject.tag == "Player") {
            other.gameObject.GetComponent<playerController>().die(); // Kills the player via a function in the player controller script.

            // Is used to offset the ice berg, centered to Icey.
            Vector2 localOffset = new Vector2(-0.5f, 0);
            Vector2 worldOffset = transform.rotation * localOffset;
            Vector2 spawnPosition = (Vector2)transform.position + worldOffset;

            Instantiate(Iceberg, spawnPosition, Quaternion.identity); // Spawns the ice berg
        }
    }

    void FixedUpdate() {
        RaycastHit2D[] hits = Physics2D.RaycastAll(new Vector2 (thisEnemy.position.x, thisEnemy_Ycentered), new Vector2(faceDir*10, 0));
        foreach (RaycastHit2D hit in hits)
        {
            if (hit.collider.gameObject.tag == "Player"){
                moveSpeed = chargeSpeed; // Starts the charge at the player
            }

            if (hit.collider.gameObject.tag != "Player" && moveSpeed == chargeSpeed) {
                chargeStopCooldown -= Time.deltaTime; // Starts the count down before stopping the charge.
                if(chargeStopCooldown <= 0) {
                    moveSpeed = defaultSpeed; // Sets the speed back to default
                    chargeStopCooldown = defaultChargeStopCooldown; // Resets the timer before Icey can stop charging.
                }
            }
        }
    }

    // Shows where the ground points are //
    void OnDrawGizmos() {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(gp_Left.position, gp_Radius);
        Gizmos.DrawWireSphere(gp_Right.position, gp_Radius);
    }
}

Notes:
Naturally everything in the editor is setup. The ground is layered ground, the player is tagged player, all the vars are set up. Also sorry about how the comments kinda get in the way. Regardless of the question, any positive feedback on my code would be nice because I’m new and there are probably many easier ways to write my code / shorten it.

Just to claify:
The question is, Why are the player / enemy randomly stoping and how should I go about fixing it.

Thanks in advance :slight_smile:

What type of collider are you using for both of them? I had an issue (and still do) where if you have box colliders (2D) on everything and then move any object using rigidbody.velocity, that object will randomly stop as if it hit an invisible collider. I got around this by using edge colliders instead of box colliders. I know my answer is 2 years late but it might help someone else i guess

Most likely also late, but I got around this by using a Capsule Collider 2D. The new bug is the player slightly jumps because of these invisible bumps.

Haha I don’t even remember this project. Thanks for the help though guys!

Changing to a different collider worked for me too, but I found another solution allowing you to keep the box collider. Give your floor, or whatever your character is trying to stand and walk on, a frictionless physics material. After adding this, my character walks around as expected!