2D Physics Broke

I have a Rigidbody2D on my playable character object that doesn’t take any changes to its velocity unless it starts from a very specific position (43.21, 0, -10). It doesn’t even apply gravity.

I’ve tried rewriting the movement script and I’ve tried completely rebuilding the player object, but the problem persists.

Something interesting is that no matter which direction I raycast in, it always comes back true. Even more peculiar is that the raycast uses a layermask to detect specifically the ground layer, but only one object in the scene is on the ground layer, and that is the ground, and the problem persists even if the ground is disabled.

I’m not sure where the problem is coming from if it’s not my code and it doesn’t have anything to do with the way my player object is built. It seems like the physics just broke somehow. Any suggestions would be super helpful.

void Move(float dir)
    {
        if (dir > 0 && !wallRight && canMove || dir < 0 && !wallLeft && canMove)
        {
            Vector2 tempVelocity = rb2d.velocity;
            tempVelocity.x = dir * moveSpeed;
            rb2d.velocity = tempVelocity;
            //set the animation state
            anim.SetBool("isRunning", true);

            //flip to match direction
                Vector3 tempScale = transform.localScale;
                tempScale.x = dir;
                transform.localScale = tempScale;
        }
        else
        {
            Stop();
        }
    }

void Stop()
    {
        rb2d.velocity = new Vector2(0, rb2d.velocity.y);
        //set the animation state
        anim.SetBool("isRunning", false);
    }

void Update () {

        //wallcheck
        //left
        int countL = rb2d.Cast(Vector2.left, cf2d, rL, 0.05f);

        if(countL > 0)
        {
            wallLeft = true;
        }
        else
        {
            wallLeft = false;
        }

        //right
        int countR = rb2d.Cast(Vector2.right, cf2d, rR, 0.05f);

        if (countR > 0)
        {
            wallRight = true;
        }
        else
        {
            wallRight = false;
        }

        //movement
        if (Input.GetAxis("Horizontal") < 0)
        {
            Move(-1);
        }
        else if (Input.GetAxis("Horizontal") > 0)
        {
            Move(1);
        }
        else
        {
            Stop();
        }


        //ground check
        int countG = rb2d.Cast(Vector2.down, cf2d, rG, 0.05f);

        if (countG > 0)
        {
            grounded = true;
            anim.SetBool("isGrounded", true);
        }
        else
        {
            grounded = false;
            anim.SetBool("isGrounded", false);
        }
}

Hard to tell you what’s wrong but you seem to be indicating that Unity physics somehow broke and that a Rigidbody2D won’t move unless it’s at at a certain position and that gravity isn’t working but that isn’t likely a Unity issue. You mention raycasts but I don’t see any in the script above (I do see collider casts so maybe you mean those).

You state that you’re selecting that only colliders on the ground layer should be returned (as specified by the ContactFilter2D) and that even if you disable all of those you get a result but you don’t specify what the result is. I mean, if the query is saying you’re touching a collider then perhaps look at what the collider is and identify it in the scene. Maybe you’ve done that but you don’t mention it. Maybe you’ve got something in the scene you’re not aware of.

A few things to note:

  • You’re doing all this per-frame but physics doesn’t run per-frame. This won’t “break physics” but you’ll have several frames before a physics update depending on your frame-rate. Just something to note. Unless of course you’re running physics per-frame in which case you can ignore that comment.
  • You seem to be constantly changing scale of the Transform. Note that you should not change the Transform when using Physics components. If you do need to do it such as using local scale to mirror the GameObject then only do so when you change direction. Changing scale causes all the colliders on that GameObject hierarchy to be recreated.