Search code examples
c#unity-game-engineacceleration

Object that slows down and stops at a specific point


In my project I have a car, with a script attached to it, for driving. In my world are traffic lights, if it is red, there spawns an object (invisible, named stop) that makes the car stop if its there, and if it is away it goes on driving with a specific variable (speed). How can I script a deceleration, and acceleration? Tried to manage it with Wait for Seconds and external coroutines, but nothing worked. In the update void:

    Ray disray = new Ray(transform.position, transform.forward);
    RaycastHit dishit;

    if (Physics.Raycast(disray, out dishit, 8) && dishit.transform.tag == "stop")
    {
        if (dishit.distance < carrange)
        {
            transform.Translate(0, 0, 0);
        }    
    }
    else
    {
        transform.Translate(0, 0, speed * Time.deltaTime);
    }

Thanks!


Solution

  • You probably need to decrease speed in a way like:

    speed = speed * (1 - f(Time.deltaTime));
    

    With f looking like:

    private float f(int ms)
    {
        float amountOfMsUntilStop = 2000.0;
        if(ms > amountOfMsUntilStop)
            return 1
        if(ms < 0)
            return 0
        return ms / amountOfMsUntilStop;
    }
    

    Of course, this is not an absolute answer, but I think you can play with the value to achieve what you want.

    This will likely make speed go like:

    enter image description here

    If I understand well your code, this is how you could change it:

    // Here we either have to brake, or to stop
    if (Physics.Raycast(disray, out dishit, 8) && dishit.transform.tag == "stop")
    {
        // Here we have to stop
        if (dishit.distance < carrange)
        {
            transform.Translate(0, 0, 0);
        }
        // Here we have to brake
        else
        {
            speed = speed * (1 - f(Time.deltaTime));
            transform.Translate(0, 0, speed * Time.deltaTime);
        }
    }
    // Here we can keep on driving
    else
    {
        transform.Translate(0, 0, speed * Time.deltaTime);
    }
    

    Edit

    While I've named it amountOfMsUntilStop, it doesn't mean it will stop in 2s with this value. It means that if for some reason, Time.deltaTime happened to be 2000 ms, then the car would go from speed to 0.

    That being said, the harder you want your car to brake, the smaller you should set this value.