Help slowly decreasing a variable to his negative value

I’m trying to make a game in which there is an object tha changes it’s speed from his current one to the negative to it (from 5 to -5 and -5 to 5) over a few seconds.

I’ve tried using an InvokeRepeating method and a waitforseconds method but nothing I did seemed to work the way I want it to.

My attempt:

speed = max speed that the object shouldgo in (either -speed or speed depending on the direction it should go in)

currspeed = speed the object moves in


private void Update()
{

    if (Input.GetKeyDown(KeyCode.Space))
    {
        changedir();
    }
    move();
}
private void move() // moves the player
{
    Vector2 movment = new Vector2(transform.position.x + currspeed, transform.position.y);
    rb.transform.position = movment;
}
private void changedir() //to change dir
{
    if (currspeed > 0)
    {
        currspeed *= 0.8f;
        StartCoroutine(Delay(0.1f,0.6f));
        StartCoroutine(Delay(0.1f, 0.4f));
        StartCoroutine(Delay(0.1f, 0.2f));
        StartCoroutine(Delay(0.1f, 0));
        StartCoroutine(Delay(0.1f, -0.2));
        StartCoroutine(Delay(0.1f, -0.4));
        StartCoroutine(Delay(0.1f, -0.6));
        StartCoroutine(Delay(0.1f, -0.8));
        StartCoroutine(Delay(0.1f, -1));

    }
    else
    {
        currspeed *= -0.8f;
        StartCoroutine(Delay(0.1f, -0.6f));
        StartCoroutine(Delay(0.1f, -0.4f));
        StartCoroutine(Delay(0.1f, -0.2f));
        StartCoroutine(Delay(0.1f, 0));
        StartCoroutine(Delay(0.1f, 0.2));
        StartCoroutine(Delay(0.1f, 0.4));
        StartCoroutine(Delay(0.1f, 0.6));
        StartCoroutine(Delay(0.1f, 0.8));
        StartCoroutine(Delay(0.1f, 1));
    } 
}
IEnumerator Delay(float time, float x) // to create a delay between chainging dirs
{
    yield return new WaitForSeconds(time);
    currspeed =speed * x; 
}

private void Update()
{

    if (Input.GetKeyDown(KeyCode.Space))
    {
        InvokeRepeating("changedir", 0f, 0.05f);
        InvokeRepeating("changedir2", 0f, 0.05f);
    }
    move();
}
private void move() // moves the player
{
    Vector2 movment = new Vector2(transform.position.x + currspeed, transform.position.y);
    rb.transform.position = movment;
}
private void changedir() //to change speed to around 0
{
    if (currspeed > 0)
    {
        currspeed -= 0.02f;
        if (currspeed < 0)
            CancelInvoke("changedir");
    }
    else
    {
        currspeed += 0.02f;
        if (currspeed > 0)
            CancelInvoke("changedir");
    } 
}
private void changedir2() //to change speed to around speed or -speed
{
    if (currspeed > speed)
    {
        currspeed -= 0.02f;
        if (currspeed < speed)
            CancelInvoke("changedir2");
    }
    else
    {
        currspeed += 0.02f;
        if (currspeed > speed)
            CancelInvoke("changedir2");
    }
}

This is all very complex for what you want to do. Keep track of elapsed time and run a sine function against it:

float ElapsedTime;
float SpeedMultiplier;

void Start(){
    ElapsedTime = 0.0f;
    SpeedMultiplier = 5.0f;
}

void Update() {
    ElapsedTIme += Time.deltaTime;
    currspeed = Mathf.Sin(ElapsedTime) * SpeedMultiplier;
}

Note: Sine always varies between -1 and 1 so use the multiplier to get your true desired end values.
You can also change how quickly this occurs by modifying the change to elapsed time. If you want it to go half speed, for example, use:

ElapsedTime += Time.deltaTime / 2;