Completely glitchy physics when using RigidBody

A little while ago I decided to convert my player movement script in my game from using a Character Controller to using a Rigidbody one since the former is so limited that it’s hard to add even basic features to it, as well as interacting more realistic with other rigidbodies in scene. But even after searching online how to do it, I had conflicting answers and they didn’t really work well.

The player now bounces everytime they move (using physics materials with bounce 0 doesn’t help), flies accross the map in specific circumstances, sometimes taking huge fall damage for no reason, can support itself on walls, and overall is a glitchy mess. Here is the parts of my script responsible for the player’s walking and jumping:

Falling (done before everything down here, inside the Update() method):

        bool Grounded = Physics.CheckSphere (GroundCheck.position, Radius, GroundMask); //Checks if player is currently on the ground or airborne//

        if (Grounded && PlayerRigidbody.velocity.y < 0f)
        {
            if (-PlayerRigidbody.velocity.y >= HarmfulVelocity)
            {
                float FallDamage = VelocityDamage * (-PlayerRigidbody.velocity.y / 10f);
                Player.Hurt (FallDamage);

                if (Player.NoiseLevel < FallingNoise)
                {
                    Player.NoiseLevel = FallingNoise;
                }

                Debug.Log ("Player hits the ground with high speed;");
            }
        }

Main movement (done inside Update() method):

        //Player main movement shenanigans//
        float X = Input.GetAxisRaw ("Horizontal") * CurrentSpeed;
        float Z = Input.GetAxisRaw ("Vertical") * CurrentSpeed;

        Vector3 MovePosition = transform.right * X + transform.forward * Z;
        GeneralVelocity = new Vector3 (MovePosition.x, PlayerRigidbody.velocity.y, MovePosition.z);
        //Player main movement shenanigans//

Main movement 2 (done after that first part, inside fixedUpdate()):

    void FixedUpdate()
    {
        PlayerRigidbody.velocity = GeneralVelocity;
    }

Jumping (done inside Update() method, after main movement):

        if (Input.GetKey(KeyCode.Space))
        {
            if (Grounded && CurrentStamina > MinStamina && PlayerStatus != PlayerState.Jumping && PlayerStatus != PlayerState.Falling)
            {
                Jump();
            }
        }

Jumping 2 (Jump() method, after all the lines shown above):

    void Jump ()
    {
        CurrentStepLimit = JumpingStepLimit;
        CurrentSlopeLimit = JumpingSlopeLimit;

        if (Player.NoiseLevel < JumpingNoise)
        {
            Player.NoiseLevel = JumpingNoise;
        }

        PlayerRigidbody.AddForce(new Vector3(PlayerRigidbody.velocity.x, PlayerRigidbody.velocity.y + Mathf.Sqrt(JumpingHeight * -2f * Physics.gravity.y), PlayerRigidbody.velocity.z), ForceMode.Impulse); //Jumping MATH//
        CurrentStamina += JumpingStaminaGain;
        PlayerStatus = PlayerState.Jumping;
        Debug.Log (this.name + " jumps;");
    }

Here are my player’s rigidbody component parameters:
Imgur: The magic of the Internet

If you need more context, please tell me so I can reply with the whole script (yes I know people can copy it, but it is garbage anyway), it has functions like stamina, sprinting, crouching, etc, and they are all working fine. I have no idea what is wrong, none of the other functions inside the script mess with rigidbody so they shouldn’t have any effect here.

Also, the problem is definetely not rigidbodies’ themselves as I have used them in the game for other objects and they work just fine, with no issues at all.

Try using addForce instead of setting velocities directly, that might help.

Line 11 in your last snippet should never exist in that form. It looks like it is about 6 or 7 different steps… just write them out one at a time so you can reason about what you’re doing and even print intermediate values.

The parts about Line 11 that immediately stand out to me as odd is that you are using velocities to calculate a force to jump. That’s never gonna be right. A force is a push. A velocity is a change in position over time.

Thanks, what should I do instead? It has been more than a year since my last physics class.

Isn’t there anything wrong with the normal movement part?

What should I do?

that is how I learnt in the tutorial, didn’t see anything wrong with it but your way might be better. How would you do it exactly?

Similar to how you did it with jump, but in movement directions instead of upwards. You can tweak the speed (force) to suit.

I tried this:

        //Player main movement shenanigans//
        float X = Input.GetAxisRaw ("Horizontal") * CurrentSpeed;
        float Z = Input.GetAxisRaw ("Vertical") * CurrentSpeed;

        Vector3 MovePosition = transform.right * X + transform.forward * Z;
        PlayerRigidbody.AddForce(new Vector3 (MovePosition.x, 0f, MovePosition.z), ForceMode.Force);
        //Player main movement shenanigans//

Now my player is extremely slow and can’t jump properly. I tried putting the speed up, now my character floats around falling extremely slowly and has a weird pull to the left (it moves very slowly to a specific direction).

As I noted a couple of days ago above, traditionally user inputs should map directly to velocity. You are mapping them to a force directly, as in if you were in vacuum on a frictionless surface, you would accelerate forever and ever and ever. That’s never going to feel right: to be snappy enough your upper speeds will be insanely fast. Otherwise it will feel sluggish.

If you feel you absolutely need to use forces instead of setting velocities directly, another way is to make the force proportional to the difference between how fast you are going now, and how fast you want to be going. This is called a “P controller,” for Proportional controller. It is the simplest type of linear control feedback system.

This means if you are going 10mph and you want to be going 20mph, you put in a proportional force of 10 x some constant, the P term. When you reach 20mph and want to be going 20mph, it puts in ZERO force.

For more googling, compare P, PD and PID controllers.

If you would like to see an example of a Unity Rigidbody FPS controller that does this, check the Unity wiki here:

https://wiki.unity3d.com/index.php/RigidbodyFPSWalker

See the lines calculating velocityChange? It uses those to add a proportional (P) force. That way once you reach the desired velocity, further input doesn’t just blindly keep accelerating you. It’s a controlled feedback system, a P controller.

I took that controller and cleaned it up a bit and added some more features, so I exported a little package for you here to play with.

It basically does what it says on the tin: Rigidbody FPS controller. Full package attached here, including a simple mouse look (not sure where I found that one… probably the same wiki?) and Y plane respawner.

6908135–809267–RigidbodyFPS.unitypackage (262 KB)

Thanks man, I will have a look

How do I check that script you sent? I placed it in the a folder in my project, Unity recognized it and installed it, but now I can’t find the script anywhere…

You can search for my name in the scripts, or it’s likely in the RigidbodyFPS directory, or you didn’t actually import it properly.

Just retested the file, it’s fine.

Oh it’s in assets, I thought it would go to Packages

Oh that’s interesting, never thought of that… No, it just goes in Assets. I’ve been using Unity since before packages, and a plain old .unitypackage file has nothing to do with the new packages system. It’s just a zipfile way to send stuff around while preserving its linkages.