Rigidbody movement script

Hello everyone,
I have tried to fix an issue with my Rigidbody movement script but can’t figure out how to do it.
The issue is that after moving, there is a delay on half a second, before the character stops. I want the character to stop faster after releasing a movement key. Do you know how to do this?
Here is my code:


`

    using System;
    using UnityEngine;
    using System.Collections;
    
    namespace Magnetized.Characters {
        [RequireComponent(typeof(Rigidbody))]
        [RequireComponent(typeof(CapsuleCollider))]
        public class Controller : MonoBehaviour {
            [Serializable]
            public class MovementSettings {
                public float ForwardSpeed; // Speed when walking forward
                public float BackwardSpeed; // Speed when walking backward
                public float StrafeSpeed; // Speed when strafing
                public float RunMultiplier; // Speed increase when running
                public KeyCode RunKey = KeyCode.LeftShift;
                public float JumpForce;
                public float AirAcceleration; // 0f if no air movement
                public float MaxAirSpeedMultiplier; // Maximum air speed
                public AnimationCurve SlopeCurveMultiplier = new AnimationCurve(new Keyframe(-90f, 1f), new Keyframe(0f, 1f), new Keyframe(60f, 0f));
                [HideInInspector] public float CurrentTargetSpeed { get; private set; }
                [HideInInspector] public float MaxAirSpeed { get { return CurrentTargetSpeed * MaxAirSpeedMultiplier; } }
    
                public bool Running { get; private set; }
    
                public void UpdateDesiredTargetSpeed(Vector2 input, bool grounded) {
                    if (input == Vector2.zero)
                        return;
                    if (input.x > 0 || input.x < 0) {
                        // Strafe
                        CurrentTargetSpeed = StrafeSpeed;
                    }
                    if (input.y < 0) {
                        // Backwards
                        CurrentTargetSpeed = BackwardSpeed;
                    }
                    if (input.y > 0) {
                        // Forwards
                        // Takes precedence over strafe speed
                        CurrentTargetSpeed = ForwardSpeed;
                    }
                    if (Input.GetKey(RunKey) && grounded) {
                        Running = true;
                    } else if (grounded) {
                        Running = false;
                    }
                    if (Running) {
                        CurrentTargetSpeed *= RunMultiplier;
                    }
                }
            }
    
            [Serializable]
            public class AdvancedSettings {
                public float GroundCheckDistance = 0.01f; // Should be set to 0.01f
                public float SlowDownRate; // Rate at which the controller stops after not receiving input
                public float SlopeLimit; // Limit at which the controller starts to slide
                public float AirResistance;
            }
         
            [SerializeField] private Camera m_Camera;
            [SerializeField] private CursorLockMode CursorLock = CursorLockMode.Locked;
            [SerializeField] private MovementSettings m_MovementSettings = new MovementSettings();
            [SerializeField] private MouseLook m_MouseLook = new MouseLook();
            [SerializeField] private AdvancedSettings m_AdvancedSettings = new AdvancedSettings();
         
            private Rigidbody m_RigidBody;
            private CapsuleCollider m_Capsule;
            private float m_YRotation;
            private Vector3 m_GroundContactNormal;
            private bool m_Jump, m_PreviouslyGrounded, m_RunningAtJump;
         
            public Vector3 Velocity {
                get { return m_RigidBody.velocity; }
            }
         
            public bool Grounded {
                get; private set;
            }
    
            public bool Sliding {
                get; private set;
            }
         
            public bool Jumping {
                get; private set;
            }
         
            public bool Running {
                get { return m_MovementSettings.Running; }
            }
    
            private void Start() {
                m_RigidBody = GetComponent();
                m_Capsule = GetComponent();
                //m_Camera = Camera.main;
                m_MouseLook.Init(transform, m_Camera.transform);
                Cursor.lockState = CursorLock;
    
                m_RigidBody.freezeRotation = true;
            }
    
            private void Update() {
                RotateView();
    
                if (!m_Jump && Input.GetButtonDown("Jump")) {
                    m_Jump = true;
                }
            }
    
            private void FixedUpdate() {
                GroundCheck();
                Vector2 input = GetInput();
    
                if (Grounded) {
                    Vector3 desiredMove = transform.forward * input.y + transform.right * input.x;
                    desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;
    
                    desiredMove *= m_MovementSettings.CurrentTargetSpeed;
    
                    if (m_RigidBody.velocity.sqrMagnitude <
                       (m_MovementSettings.CurrentTargetSpeed * m_MovementSettings.CurrentTargetSpeed)) {
                        m_RigidBody.AddForce(desiredMove * SlopeMultiplier(), ForceMode.Impulse);
                    }
    
                    m_RigidBody.drag = m_AdvancedSettings.SlowDownRate;
    
                    if (m_Jump) {
                        m_RigidBody.drag = 0f;
                        m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
                        m_RigidBody.AddForce(new Vector3(0f, m_MovementSettings.JumpForce, 0f), ForceMode.Impulse);
                        Jumping = true;
                    }
    
                    if (!Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f) {
                        m_RigidBody.Sleep();
                    }
                } else if (Sliding) {
                    m_RigidBody.drag = 0f; //m_AdvancedSettings.SlowDownRate;
                    //m_RigidBody.AddForce(new Vector3(m_GroundContactNormal.x, 0f, m_GroundContactNormal.y));
                    AddAirAcceleration(input);
                } else {
                    m_RigidBody.drag = 0f;
                    AddAirAcceleration(input);
                }
                m_Jump = false;
            }
    
            private float SlopeMultiplier() {
                float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
                return m_MovementSettings.SlopeCurveMultiplier.Evaluate(angle);
            }
    
            private Vector2 GetInput() {
                Vector2 input = new Vector2 {
                    x = Input.GetAxis("Horizontal"),
                    y = Input.GetAxis("Vertical")
                };
                m_MovementSettings.UpdateDesiredTargetSpeed(input, Grounded);
    
                return input;
            }
    
            private void AddAirAcceleration(Vector2 input) {
                m_RigidBody.AddForce(new Vector3(-m_RigidBody.velocity.x, 0f, -m_RigidBody.velocity.z) * m_AdvancedSettings.AirResistance);
                if (m_RigidBody.velocity.sqrMagnitude < (m_MovementSettings.MaxAirSpeed * m_MovementSettings.MaxAirSpeed)) {
                    Vector3 desiredMove = transform.forward * input.y + transform.right * input.x;
                    desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;
    
                    desiredMove *= m_MovementSettings.AirAcceleration;
    
                    m_RigidBody.AddForce(desiredMove, ForceMode.Impulse);
                }
            }
    
            private void RotateView() {
                m_MouseLook.LookRotation(transform, m_Camera.transform);
            }
    
            private void GroundCheck() {
                m_PreviouslyGrounded = Grounded;
    
                RaycastHit hitInfo;
                if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
                                  ((m_Capsule.height/2f) - m_Capsule.radius) + m_AdvancedSettings.GroundCheckDistance)) {
                    if (Vector3.Angle(hitInfo.normal, Vector3.up) > m_AdvancedSettings.SlopeLimit) {
                        Sliding = true;
                    } else {
                        Grounded = true;
                    }
                    m_GroundContactNormal = hitInfo.normal;
                } else {
                    Grounded = false;
                    Sliding = false;
                    m_GroundContactNormal = Vector3.up;
                }
                if (!m_PreviouslyGrounded && Grounded && Jumping) {
                    Jumping = false;
                }
            }
        }
    }

`

Hi,
if I understand you correctly, you’re able to achieve this by lowering the slow down rate in the Inspector view.
alt text

So the reason there is lag is the input for Horizontal and Vertical gravity setting is too low.

Go to “Project settings/Input” expand the horizontal and vertical inputs and change the gravity to something really high like 1000

Also the script that comes with the rigid body component never uses the slow down rate variable (Just sets it to 5?) so I fixed it. It now uses the original drag from the RB component when airborne for more predictable movement.

using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

namespace UnityStandardAssets.Characters.FirstPerson
{
    [RequireComponent(typeof (Rigidbody))]
    [RequireComponent(typeof (CapsuleCollider))]
    public class RigidbodyFirstPersonController : MonoBehaviour
    {
        [Serializable]
        public class MovementSettings
        {
            public float ForwardSpeed = 8.0f;   // Speed when walking forward
            public float BackwardSpeed = 4.0f;  // Speed when walking backwards
            public float StrafeSpeed = 4.0f;    // Speed when walking sideways
            public float RunMultiplier = 2.0f;   // Speed when sprinting
	        public KeyCode RunKey = KeyCode.LeftShift;
            public float JumpForce = 30f;
            public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
            [HideInInspector] public float CurrentTargetSpeed = 8f;

#if !MOBILE_INPUT
            private bool m_Running;
#endif

            public void UpdateDesiredTargetSpeed(Vector2 input)
            {
	            if (input == Vector2.zero) return;
				if (input.x > 0 || input.x < 0)
				{
					//strafe
					CurrentTargetSpeed = StrafeSpeed;
				}
				if (input.y < 0)
				{
					//backwards
					CurrentTargetSpeed = BackwardSpeed;
				}
				if (input.y > 0)
				{
					//forwards
					//handled last as if strafing and moving forward at the same time forwards speed should take precedence
					CurrentTargetSpeed = ForwardSpeed;
				}
#if !MOBILE_INPUT
	            if (Input.GetKey(RunKey))
	            {
		            CurrentTargetSpeed *= RunMultiplier;
		            m_Running = true;
	            }
	            else
	            {
		            m_Running = false;
	            }
#endif
            }

#if !MOBILE_INPUT
            public bool Running
            {
                get { return m_Running; }
            }
#endif
        }


        [Serializable]
        public class AdvancedSettings
        {
            public float groundCheckDistance = 0.01f; // distance for checking if the controller is grounded ( 0.01f seems to work best for this )
            public float stickToGroundHelperDistance = 0.5f; // stops the character
            public float slowDownRate = 20f; // rate at which the controller comes to a stop when there is no input
            public bool airControl; // can the user control the direction that is being moved in the air
            [Tooltip("set it to 0.1 or more if you get stuck in wall")]
            public float shellOffset; //reduce the radius by that ratio to avoid getting stuck in wall (a value of 0.1f is nice)
        }


        public Camera cam;
        public MovementSettings movementSettings = new MovementSettings();
        public MouseLook mouseLook = new MouseLook();
        public AdvancedSettings advancedSettings = new AdvancedSettings();


        private Rigidbody m_RigidBody;
        private CapsuleCollider m_Capsule;
        private float m_YRotation;
        private Vector3 m_GroundContactNormal;
        private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsGrounded;
		private float rbDrag;//Set a Float for storing the original drag from the Rigidbody


        public Vector3 Velocity
        {
            get { return m_RigidBody.velocity; }
        }

        public bool Grounded
        {
            get { return m_IsGrounded; }
        }

        public bool Jumping
        {
            get { return m_Jumping; }
        }

        public bool Running
        {
            get
            {
 #if !MOBILE_INPUT
				return movementSettings.Running;
#else
	            return false;
#endif
            }
        }


        private void Start()
        {
            m_RigidBody = GetComponent<Rigidbody>();
			rbDrag = GetComponent<Rigidbody>().drag; //Get the drag from Rigidbody component
            m_Capsule = GetComponent<CapsuleCollider>();
            mouseLook.Init (transform, cam.transform);
        }


        private void Update()
        {
            RotateView();

            if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
            {
                m_Jump = true;
            }
        }


        private void FixedUpdate()
        {
            GroundCheck();
            Vector2 input = GetInput();


            if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
            {
				
                // always move along the camera forward as it is the direction that it being aimed at
                Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
                desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;

                desiredMove.x = desiredMove.x*movementSettings.CurrentTargetSpeed;
                desiredMove.z = desiredMove.z*movementSettings.CurrentTargetSpeed;
                desiredMove.y = desiredMove.y*movementSettings.CurrentTargetSpeed;
                if (m_RigidBody.velocity.sqrMagnitude <
                    (movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
                {
                    m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
					
                }
            }

            if (m_IsGrounded)
            {
                m_RigidBody.drag = advancedSettings.slowDownRate + rbDrag;//set the drag to the slow down rate when grounded

                if (m_Jump)
                {
                    m_RigidBody.drag =rbDrag;//Set drag to orig RigidBody Drag when airborn
                    m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
                    m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
                    m_Jumping = true;
                }

                if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
                {
                    m_RigidBody.Sleep();
                }
            }
            else
            {
                m_RigidBody.drag = rbDrag;//Set drag to orig RigidBody Drag when airborn
                if (m_PreviouslyGrounded && !m_Jumping)
                {
                    StickToGroundHelper();
                }
            }
            m_Jump = false;
        }


        private float SlopeMultiplier()
        {
            float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
            return movementSettings.SlopeCurveModifier.Evaluate(angle);
        }


        private void StickToGroundHelper()
        {
            RaycastHit hitInfo;
            if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
                                   ((m_Capsule.height/2f) - m_Capsule.radius) +
                                   advancedSettings.stickToGroundHelperDistance, Physics.AllLayers, QueryTriggerInteraction.Ignore))
            {
                if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f)
                {
                    m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
                }
            }
        }


        private Vector2 GetInput()
        {
            
            Vector2 input = new Vector2
                {
                    x = CrossPlatformInputManager.GetAxis("Horizontal"),
                    y = CrossPlatformInputManager.GetAxis("Vertical")
                };
			movementSettings.UpdateDesiredTargetSpeed(input);
            return input;
        }


        private void RotateView()
        {
            //avoids the mouse looking if the game is effectively paused
            if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;

            // get the rotation before it's changed
            float oldYRotation = transform.eulerAngles.y;

            mouseLook.LookRotation (transform, cam.transform);

            if (m_IsGrounded || advancedSettings.airControl)
            {
                // Rotate the rigidbody velocity to match the new direction that the character is looking
                Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
                m_RigidBody.velocity = velRotation*m_RigidBody.velocity;
            }
        }

        /// sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
        private void GroundCheck()
        {
            m_PreviouslyGrounded = m_IsGrounded;
            RaycastHit hitInfo;
            if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
                                   ((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance, Physics.AllLayers, QueryTriggerInteraction.Ignore))
            {
                m_IsGrounded = true;
                m_GroundContactNormal = hitInfo.normal;
            }
            else
            {
                m_IsGrounded = false;
                m_GroundContactNormal = Vector3.up;
            }
            if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
            {
                m_Jumping = false;
            }
        }
    }
}