rigidbody movement problem

I have a very specific problem with my rigid body controller. I made my controls add force to the players rigid body, which works ok; so i than added a way for a player to move diagonally, but if the player moves diagonally and one movement key is released the player briefly stops with very visible hitch since the camera is following the player.

I have setup my controller to use FixedUpdate() and also my camera usses FixedUpdate(). Is this correct approach?

How do i make my player not make a brief stop when one of the movement keys is released eg. if i hold down up and right movement key and than release just one of those two, the player briefly stops? I don’t want this to happen. Here is my player movement part of code

if (isGrounded == true)
        {
            // move player forward
            if (Input.GetKey(KeyCode.W))
            {
                rb.AddForce(transform.forward * speed * Time.deltaTime);
                rb.velocity = Mathf.Clamp (rb.velocity.magnitude, 0, speed) * rb.velocity.normalized;
            }
            // move player backward
            if (Input.GetKey(KeyCode.S))
            {
                rb.AddForce(-(transform.forward) * speed * Time.deltaTime);
                rb.velocity = Mathf.Clamp (rb.velocity.magnitude, 0, speed) * rb.velocity.normalized;
            }
            // move player left
            if (Input.GetKey(KeyCode.A))
            {
                rb.AddForce(-(Camera.main.transform.right) * speed * Time.deltaTime);
                rb.velocity = Mathf.Clamp (rb.velocity.magnitude, 0, speed) * rb.velocity.normalized;
            }
            // move player right
            if (Input.GetKey(KeyCode.D))
            {
                rb.AddForce(Camera.main.transform.right * speed * Time.deltaTime);
                rb.velocity = Mathf.Clamp (rb.velocity.magnitude, 0, speed) * rb.velocity.normalized;
            }

            // move if direction is combined
            if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D) ||
                Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.D))
            {
                rb.AddForce(transform.forward * (speed / 8 * Time.deltaTime)); // ??? not sure about this math here - seems to give desired result
                rb.velocity = Mathf.Clamp (rb.velocity.magnitude, 0, speed) * rb.velocity.normalized;
            }

            // stop moving if movement keys are released
            // this also causes the player to briefly stop in place if combination of direction keys is held down and than one gets released
            if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D))
            {
                if (rb.velocity.magnitude > 0)
                {
                    //rb.velocity = Vector3.zero;
                    //rb.angularVelocity = Vector3.zero;

                    rb.AddForce(-rb.velocity, ForceMode.VelocityChange);
                }
            }

            // stop moving if opposing direction keys are pressed
            if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.D))
            {
                rb.velocity = Vector3.zero;
                rb.angularVelocity = Vector3.zero;
            }

            // jump
            if (Input.GetKeyDown("space"))
                rb.AddForce(0, 500.0f, 0);
        }
    }

You should never used FixedUpdate to poll Input. Instead you should calculate a direction vector in Update and multiply it by your movement speed. Finally, use FixedUpdate to apply the force in the desired direction with AddRelativeForce. Someone please correct me if I’m wrong but I don’t think you need to multiply the movement speed by Time.deltaTime if the actual force is applied in FixedUpdate. FixedUpdate runs at a constant time(hence the name…)…

private Rigidbody rigidBody;
private Vector3 force;
private float movementSpeed;

void Update()
{
   this.force = this.CalculateDirection() * this.movementSpeed;
}

void FixedUpdate()
{
   this.rigidBody.AddRelativeForce(this.force, ForceMode.Force);
}

private Vector3 CalculateDirection()
{
   Vector3 direction = Vector3.zero;
   if (Input.GetKey(KeyCode.W))
   {
     direction.z = 1.0f;
   }
   else if (Input.GetKey(KeyCode.S))
   {
     direction.z = -1.0f;
   }
   if (Input.GetKey(KeyCode.A))
   {
     direction.x = -1.0f;
   }
   else if (Input.GetKey(KeyCode.D))
   {
     direction.x = 1.0f;
   }
   return direction.normalized;
}

not being a fan of hard coded inputs you can do something like

private Vector3 CalculateDirection()
{
   return new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")).normalized;
}

which has the added advantage of handling opposing key presses too

I found that this code is not triggering, how do i make the rigid body stop in place instantly if none of movement keys are pressed?

            // stop moving if movement keys are released
            // this also causes the player to briefly stop in place if combination of direction keys is held down and than one gets released
            if (Input.GetKeyUp(KeyCode.W) && Input.GetKeyUp(KeyCode.S) && Input.GetKeyUp(KeyCode.A) && Input.GetKeyUp(KeyCode.D))
            {
                if (rb.velocity.magnitude > 0)
                {
                    //rb.velocity = Vector3.zero;
                    //rb.angularVelocity = Vector3.zero;
                    rb.AddForce(-rb.velocity, ForceMode.VelocityChange);
                }
            }