Accelerate object with slider problem

Hello!

Im working on a slider movement for objects, the slider and movement works for the object, but when you drag the slider to 100% or what ever value, the object also instantly accelerate with the slider value.

I have AccelRate in the FixedUpdate, but it is ignored of some reason, the thing is when you move the slider,
the object shall accelerate slowly untill it reach the value of the slider + with the rate AccelRate ofc, not instantly.

Just like a car when you put the pedal to the metall, the car gain speed to the “rate” of your pedal level after some time.

CODE:

public Slider Impulseslider;

    public void ImpulseSlider(string sliderID)
    {
        CurSpeed = Impulseslider.value;
    }

    void FixedUpdate ()
    {
        Slidervalue = CurSpeed;


        if (Impulseslider.value > 0)
        {
            Slidervalue = Mathf.Min(Slidervalue + AccelRate * Time.deltaTime, MaxSpeed);
            GetComponent<Rigidbody>().velocity = transform.forward * CurSpeed;
            impulse_active = true;
        } else {        
            Slidervalue = Mathf.Max(Slidervalue - DeAccel * Time.deltaTime * 1.5f, 0);
            GetComponent<Rigidbody>().velocity = transform.forward * CurSpeed;
            impulse_active = false;
        }
    }
}

First, you should get in the habit of caching the rigidbody, as GetComponent is a somewhat expensive call.

The reason it doesn’t accelerate is that you are setting the speed to CurSpeed, which I assume is set by the slider in the ImpulseSlider method. All the math you use to update Slidervalue doesn’t seem to affect CurSpeed, and so is not used to set the speed at all.

Finally, I’d recommend you rather use AddForce instead of doing this calculation yourself, should be easier and probably more performant.

I forgot to post this

public Component Ship;
void Start()
    {
        Ship = GetComponent<Rigidbody>();
    }

The ship do accelerate from 0-100, its just that if you instantly drag the slider up to 50, the object also accelerate to 50 instead of accelerate slowly.
Could you please post a example for AddForce?

In your FixedUpdate, you’d do something like this

Ship.AddForce(transform.forward * AccelRate, ForceMode.Acceleration);

You then also want to limit the speed, as you have in your code.

if (Ship.velocity.sqrMagnitude > maxSpeedSqr) 
{
    Ship.velocity = Ship.velocity.normalized * maxSpeed;
}

maxSpeedSqr should here be the square of your wanted max speed. We use it together with sqrMagnitude in the if check, because computing square roots is a slow operation.

To elaborate, I hope I’m not over-complicating things here, but while this task seems deceivingly simple it is actually part of a separate field of study in engineering called control systems engineering. To do this properly, what you need is something called a PID controller.

Take a look at this forum thread for an implementation you could try to use.

Ok this works as it should do, but having problem to slow down the ship, i know its the else that isnt correct. But im not sure about how i should do it

    void FixedUpdate ()
    {
        Slidervalue = CurentSpeed;

        if (CurentSpeed > MaxSpeed)
            CurentSpeed = MaxSpeed;
       

        if (Impulseslider.value > 0)
        {
            Ship.AddForce(transform.forward * CurentSpeed * AccelerateRate, ForceMode.Acceleration);
            impulse_active = true;

        } else {        

            Ship.AddForce(transform.forward * CurentSpeed * Deccelerate, ForceMode.Acceleration);
            impulse_active = false;
        }

        if (Input.GetAxis("Turn") > 0)
        {
            //GetComponent<Rigidbody>().MoveRotation = transform.forward * turnspeed;
        }
    }
}

Deccelerate needs to be a negative value in this case, or you can just put -Deccelerate.

That didnt work, i tried both ways and it keeps the speed it had when i turn the slider to a lower level

Ship.AddForce(transform.forward * CurentSpeed - Decacelerate, ForceMode.Acceleration);

Ship.AddForce(transform.forward * CurentSpeed * -Decacelerate, ForceMode.Acceleration);

You probably need a much larger decelerate value then, as you need to overcome the forward momentum.

Doesnt matter if i have value 10000, it still dont slow down or stop of some reason

Are you sure the slider actually goes negative?

Debug.Log(Impulseslider.value);

Yes i have the value of the slider shown in the inspector, it goes up and down with the on-screen slider + impulse_active =true; bool is also working.

Take a look at the attached example that I threw together. It uses a simple PD controller to smooth out the forces, adjust the pk and pd variables to tune the controller.

Hope this helps?

2882411–211662–sliderspeed.unitypackage (42.2 KB)

Idk if im doing something wrong or if it is the script, if i change the max speed to 60 as i use as standard, the object goes instantly to the end of the universe and unity getting a error and pausing, also the slider goes from the left side screen all the way to the right side.
ERROR

rigidbody.force assign attempt for 'Romulan_BOP' is not valid. Input force is { -0.000000, -0.000000, -Infinity }.
UnityEngine.Rigidbody:AddForce(Vector3, ForceMode)

But i did this earlier today and this works as i want it to do, my next step is to make it turn in a curve with banking, and so far i have failed to do so.

    void FixedUpdate ()
    {
        CurrentAccelerate = Ship.velocity.magnitude;
        ImpulsSlidervalue = CurentSpeed;


        if (CurentSpeed > MaxSpeed)
            CurentSpeed = MaxSpeed;   

        if (Impulseslider.value > 0)
        {
            targetPosition += transform.forward * CurentSpeed * Time.deltaTime;
            impulse_active = true;

        } else {
            targetPosition += transform.forward * CurentSpeed * Time.deltaTime;
            impulse_active = false;
        }

        if (Input.GetAxis("Turn") != 0)
        {
            //targetPosition += transform.right * Input.GetAxisRaw("Horizontal") * CurentSpeed * Time.deltaTime;
        }

        var currentPosition = SgtHelper.Dampen3(transform.position, targetPosition, AccelerateRate, Time.deltaTime, 0.1f);
        SgtHelper.SetPosition(transform, currentPosition);
        }
    }