Making RB movement smoother/curvy. C#.

Hello. I am trying to make my rb movement more smooth/ curvy, rite now it only moves with rough edges when changing move direction.

Current movement


Desired movement

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
 // Movement
 [Header("Movement")]
 public float speedometer;
 [SerializeField, Range(0f, 40f)] float GroundSpeed = 10, GroundAccelX = 10, GroundAccelZ;
 [SerializeField, Range(0f, 20f)] float AirSpeed = 3;
 [SerializeField, Range(0f, 1f)] float counterMovementGroundX, counterMovementGroundZ;
 [SerializeField, Range(0f, 1f)] float counterMovementAirX, counterMovementAirZ;



 // float maxSpeed;

 public Vector3 velocity, desiredVelocity, velocityChange;

 public float rayHitdistance = 1;
 public LayerMask whatIsGround;

 //Jump
 [Header("Jump")]
 [SerializeField, Range(0f, 20f)] float jumpHight = 5;
 bool grounded;

 // Inputs
 float inputX, inputZ;
 bool inputJump;

 Rigidbody rb;

 private void Awake()
 {
     rb = GetComponent<Rigidbody>();
 }


 void Inputs()
 {
     inputX = Input.GetAxisRaw("Horizontal");
     inputZ = Input.GetAxisRaw("Vertical");

     inputJump |= Input.GetButtonDown("Jump");
 }

 void Update()
 {
     Inputs();

     speedometer = rb.velocity.magnitude;
 }

 void FixedUpdate()
 {


     if (Mathf.Abs(inputX) > 0 || Mathf.Abs(inputZ) > 0)
     {
         MoveVelocity();
     }
     else if (OnGround())
     {
         CounterMovementGround(counterMovementGroundX, counterMovementGroundZ);
     }

     if (inputJump && OnGround())
     {
         Jump();
         inputJump = false;

     }

    // UpdateState();
 }

 // used for reseting the volicty after jumping
 void UpdateState()
 {
     if (rb.velocity.y < -0.1f)
     {
         if (OnGround())
         {
             rb.velocity = Vector3.zero;
         }
     }
 }

 void Jump()
 {
     float mag = rb.velocity.magnitude;
     float jumpForce = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHight);

     Vector3 vel = transform.InverseTransformDirection(rb.velocity); // velocity drag gets converted from word space to local space
     Vector3 desiredVel = vel * mag;
     //   rb.velocity = transform.TransformDirection(desiredVel); // velocity drag gets converted from local space to world space      

     rb.AddRelativeForce(Vector3.up * jumpForce, ForceMode.Impulse);
     // rb.AddRelativeForce(desiredVel, ForceMode.Impulse);



 }

 void CounterMovementGround(float xCounter, float zCounter)
 {
     Vector3 vel = transform.InverseTransformDirection(rb.velocity); // velocity drag gets converted from word space to local space
     vel.x *= xCounter;
     vel.z *= zCounter;
     rb.velocity = transform.TransformDirection(vel); // velocity drag gets converted from local space to world space      
 }

 public float Movespeed;
 void MoveVelocity()
 {

     //float Movespeed = OnGround() ? GroundSpeed : AirSpeed;

     if (OnGround())
     {
         Movespeed = GroundSpeed;
     }
     else
     {
         Movespeed = Mathf.Lerp(GroundSpeed, AirSpeed, 5.0f *  Time.fixedDeltaTime);
     }

     Vector3 desiredVelocity = new Vector3(inputX, 0f, inputZ).normalized * Movespeed;
     desiredVelocity = transform.TransformDirection(desiredVelocity);

     velocity = rb.velocity;


     velocityChange = (desiredVelocity - velocity);


     velocityChange.x = Mathf.Clamp(velocityChange.x, -Movespeed, Movespeed);
     velocityChange.z = Mathf.Clamp(velocityChange.z, -Movespeed, Movespeed);
     velocityChange.y = 0;



     rb.AddForce(velocityChange, ForceMode.VelocityChange);

 }

 bool OnGround()
 {
     if (Physics.Raycast(transform.position, Vector3.down, rayHitdistance, whatIsGround) ||
                 Physics.Raycast(transform.position - new Vector3(0.5f, 0, 0), Vector3.down, rayHitdistance, whatIsGround) ||
                 Physics.Raycast(transform.position - new Vector3(-0.5f, 0, 0), Vector3.down, rayHitdistance, whatIsGround) ||
                 Physics.Raycast(transform.position - new Vector3(0, 0, 0.5f), Vector3.down, rayHitdistance, whatIsGround) ||
                 Physics.Raycast(transform.position - new Vector3(0, 0, -0.5f), Vector3.down, rayHitdistance, whatIsGround))
     {
         Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.down) * rayHitdistance, Color.green);
         Debug.DrawRay(transform.position - new Vector3(0.5f, 0, 0), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.green);
         Debug.DrawRay(transform.position - new Vector3(-0.5f, 0, 0), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.green);
         Debug.DrawRay(transform.position - new Vector3(0, 0, 0.5f), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.green);
         Debug.DrawRay(transform.position - new Vector3(0, 0, -0.5f), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.green);

         return true;


     }
     else
     {
         Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.down) * rayHitdistance, Color.red);
         Debug.DrawRay(transform.position - new Vector3(0.5f, 0, 0), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.red);
         Debug.DrawRay(transform.position - new Vector3(-0.5f, 0, 0), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.red);
         Debug.DrawRay(transform.position - new Vector3(0, 0, 0.5f), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.red);
         Debug.DrawRay(transform.position - new Vector3(0, 0, -0.5f), transform.TransformDirection(Vector3.down) * rayHitdistance, Color.red);

         return false;
     }
 }
 }

Hi @matejaizverieas

what you are looking for is called interpolation, there are multiple possible solutions.

One that is really awesome and fast is called “Bezier Curves”, you can find good tutorials here and here