title: Weird collision bug in Unity 2d game
body: <p><a href="https://github.com/gioragutt/GameOfThrowsUnity/tree/master/GameOfThrows/Assets/Scripts" rel="nofollow noreferrer">Github Repository (Scripts folder, has all code in .cs files)</a></p>
  
  <p>I have this weird collision bug in unity, here's a gif of it:</p>
  
  <p><a href="https://i.stack.imgur.com/02aTe.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/02aTe.gif" alt="GIF"></a></p>
  
  <p>Recreating: In the gif, for example, I press both <kbd>Left arrow</kbd> and <kbd>Up arrow</kbd> until the velocity normalizes, and I get some why stuck in a block.</p>
  
  <p>I've had this before with my own collision algorithm when I did the game in XNA, hoped this would not happen in Unity.</p>
  
  <p>This is the player script <code>PlayerMovement</code>:</p>
  
  <pre><code>using UnityEngine;
  using UnityEngine.UI;
  
  namespace Assets.Scripts
  {
      public enum Directions
      {
          Back,
          Left,
          Front,
          Right,
          Idle = -1
      }
  
      public class PlayerMovement : MonoBehaviour
      {
          #region Public Members
  
          /// &lt;summary&gt;
          /// Maximum speed of the player (Accelerated to over a period of time)
          /// &lt;/summary&gt;
          public float speed;
  
          /// &lt;summary&gt;
          /// Debug UI.Text element
          /// &lt;/summary&gt;
          public Text debugText;
  
          #endregion
  
          #region Constants
  
          /// &lt;summary&gt;
          /// Constant for decaying the velocity on updates
          /// &lt;/summary&gt;
          private const float VELOCITY_DECAY_FACTOR = 0.85f;
  
          /// &lt;summary&gt;
          /// Constant to convert normal speed sizes to fit the scale
          /// Of UnityEngine.Vector2
          /// &lt;/summary&gt;
          private const float HUMAN_TO_VECTOR_SCALE_FACTOR = 850f;
  
          /// &lt;summary&gt;
          /// Constant to set the base speed of the player animation
          /// &lt;/summary&gt;
          private const float BASE_ANIM_SPEED = 0.7f;
  
          /// &lt;summary&gt;
          /// Constant to slightly reduce the animation speed after 
          /// It is multiplied by the velocity of the player
          /// &lt;/summary&gt;
          private const float POST_VELOCITY_MULTIPLICATION_ANIM_SPEED_FACTOR = 0.5f;
  
          /// &lt;summary&gt;
          /// Constant to set the animation speed
          /// &lt;/summary&gt;
          private const float ANIM_SPEED_MODIFIER = BASE_ANIM_SPEED * POST_VELOCITY_MULTIPLICATION_ANIM_SPEED_FACTOR;
  
          /// &lt;summary&gt;
          /// Epsilon before velocity zerofication
          /// &lt;/summary&gt;
          private const float VELOCITY_EPSILON = 0.1f;
  
          #endregion
  
          #region Private Members
  
          private Rigidbody2D rb2D;
          private Vector2 velocity;
          private Animator animator;
          private Directions dir = Directions.Idle;
  
          #endregion
  
          #region Game Loop Methods
  
          private void Awake()
          {
              animator = GetComponent&lt;Animator&gt;();
              rb2D = GetComponent&lt;Rigidbody2D&gt;();
          }
  
          private void FixedUpdate()
          {
              float vertical = Input.GetAxisRaw("Vertical");
              float horizontal = Input.GetAxisRaw("Horizontal");
              UpdateVelocity(horizontal, vertical);
              UpdateAnimation(horizontal, vertical);
              UpdateMovment();
          }
  
          #endregion
  
          #region Animation Methods
  
          private void UpdateAnimation(float horizontal, float vertical)
          {
              UpdateAnimation(new Vector2(horizontal, vertical));
          }
  
          private void UpdateAnimation(Vector2 input)
          {
              Directions direction;
  
              if (input.y &gt; 0)
                  direction = Directions.Back;
              else if (input.y &lt; 0)
                  direction = Directions.Front;
              else if (input.x &gt; 0)
                  direction = Directions.Right;
              else if (input.x &lt; 0)
                  direction = Directions.Left;
              else
                  direction = Directions.Idle;
  
              SetDirection(direction);
          }
  
          private void SetDirection(Directions value)
          {
              animator.SetInteger("Direction", (int)value);
              dir = value;
          }
  
          #endregion
  
          #region Movement Methods
  
          private void UpdateMovment()
          {
              rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
              KinematicsDebugPrints();
              ApplySpeedDecay();
          }
  
          private string GetDebugPrintDetails()
          {
              return string.Format("HOR : {0}\nVER : {1}\nDIR : {2}:{3}\nX : {4}\nY : {5}",
                  velocity.x,
                  velocity.y,
                  animator.GetInteger("Direction").ToString().PadLeft(2),
                  (Directions)animator.GetInteger("Direction"),
                  rb2D.position.x,
                  rb2D.position.y);
          }
  
          private void KinematicsDebugPrints()
          {
              var details = GetDebugPrintDetails();
              debugText.text = details;
              Debug.Log(details);
          }
  
          private void UpdateVelocity(float horizontal, float vertical)
          {
              if (vertical != 0)
                  velocity.y += Mathf.Sign(vertical) * speed / HUMAN_TO_VECTOR_SCALE_FACTOR;
              if (horizontal != 0)
                  velocity.x += Mathf.Sign(horizontal) * speed / HUMAN_TO_VECTOR_SCALE_FACTOR;
              animator.speed = ANIM_SPEED_MODIFIER * velocity.MaxOfXandY() ;
          }
  
          private void ApplySpeedDecay()
          {
              if (velocity == Vector2.zero) return;
  
              velocity *= VELOCITY_DECAY_FACTOR;
              velocity = velocity.ZerofiyTinyValues(0.1f);
          }
  
          #endregion
      }
  }
  </code></pre>
  
  <p>This is the player object currently:</p>
  
  <p><a href="https://i.stack.imgur.com/heZ2R.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/heZ2R.png" alt="player"></a></p>
  
  <p>And this is the wall object (prefab is the same for all walls except for the image:</p>
  
  <p><a href="https://i.stack.imgur.com/qRbSi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/qRbSi.png" alt="WALL"></a></p>
  
  <p>This is a gif of my other bug:</p>
  
  <p><a href="https://i.imgur.com/n7lyIek.gif" rel="nofollow noreferrer"><img src="https://i.imgur.com/n7lyIek.gif" alt="bug two"></a></p>
  
  <p>This is how the collision box and circles look like:</p>
  
  <p><a href="https://i.stack.imgur.com/BUXof.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/BUXof.png" alt="new collision boxes"></a></p>
  
  <p>And this are the details from the inspector</p>
  
  <p><a href="https://i.stack.imgur.com/TtG6K.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TtG6K.png" alt="new inspector"></a></p>
  
  <hr>
  
  <p>So after speaking with Hamza Hasan, he helped me to turn all the outer wall box colliders into four continues colliders, one per side(top, bottom, left, right).</p>
  
  <p>The code for it is on the <a href="https://github.com/gioragutt/GameOfThrowsUnity/blob/master/GameOfThrows/Assets/Scripts/BoardManager.cs" rel="nofollow noreferrer"><code>BoardManager</code></a> script in the <code>CreateWallsColliders</code> method.</p>
  
  <p>This is how the scene currently looks like in the scene editor:</p>
  
  <p><a href="https://i.stack.imgur.com/7hheJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7hheJ.png" alt="new scene editor"></a></p>