Why is my Coroutine not starting?

I’m trying to make my character wall jump, so when I hit the wall and press jump, I add a Force which changes my character’s x speed higher than its normal MaxSpeed, so the character is away from the wall and is not able to climb infinitely from it. Then, I want to return my MaxSpeed back to its normal value (I stored its default value in a variable in Start) gradually, so I’m using a Coroutine. This is the code I’m using

maxSpeed = 6
wallJumpSpeed = 15
defaultMaxSpeed = maxSpeed (in Start) = 6
h = Horizontal Axis input

//This is in the FixedUpdate
if (wallJump && !touchGround)
                {
                    maxSpeed = wallJumpSpeed;
                    rb2d.velocity = new Vector2(0f, rb2d.velocity.y);
                    rb2d.AddForce(Vector2.left * wallJumpSpeed * h, ForceMode2D.Impulse);
                    wallJump = false;
                    StartCoroutine(ReduceValue(maxSpeed, defaultMaxSpeed, 0.15f));
                }

And this is the Coroutine

public IEnumerator ReduceValue(float objective, float target, float reducer)
    {
        while (objective > target)
        {
            objective -= reducer;
            yield return null;
        }
        objective = target;
        yield return null;
    }

Now, when I make a Wall Jump, it works properly until the part when I want to reduce the speed, it’s just not working and the MaxSpeed stays at the WallJumpSpeed. What am I doing wrong for the coroutine not to work? I have another item which boosts the speed for a moment and it works nicely by using the exact same Coroutine. Why is it not working with my WallJump?

From what I can see, you’re only modifying the “objective” float, which is a coroutine parameter, and that stays inside the coroutine, the modified value is never applied to a class variable or returned through yield or an out parameter. I’m not quite sure how is the other coroutine you mention working.

I mean the Coroutine is referenced in other place, where I use a “boost” item, and then slows down the speed gradually, it’s exactly the same, the objective is the current maxSpeed, the target is the defaultMaxSpeed, and thebreducer in still 0.15f.

There, the Coroutine works properly, I don’t know why it doesn’t work in this case

because floats pass as values and not as reference. change it like this:

    public IEnumerator ReduceValue( ref float objective, ref float target, float reducer)
        {
            while (objective > target)
            {
                objective -= reducer;
                yield return null;
            }
            objective = target;
            yield return null;
        }

and

   StartCoroutine(ReduceValue(ref maxSpeed,ref defaultMaxSpeed, 0.15f));

It doesn’t work, the Coroutine method gives me an error

public IEnumerator ReduceValue(ref float objective, ref float target, float reducer)
    {
        while (objective > target)
        {
            objective -= reducer;
            yield return null;
        }
        objective = target;
        yield return null;
    }

It tells me that (sorry if it’s not translated well) the iterators can’t have in, out or ref parameters

true, well I guess you have to use the actual values in the coroutine then like this:

    public IEnumerator ReduceValue(float reducer)
        {
            while (maxSpeed> defaultMaxSpeed)
            {
                maxSpeed-= reducer;
                yield return null;
            }
            maxSpeed= defaultMaxSpeed;
            yield return null;
        }
1 Like

Yeah, now it works. I wanted to keep that Coroutine open to reduce any other value in case I needed it, but it seems it’s not possible, so I’ll stick with that one for now, I don’t need to reduce other values anyway for now. Thank you very much!

I guess you can do it if you wrap it in a class like this:

public class floatAsRef{

public float fv;
}

public IEnumerator ReduceValue(floatAsRef objective, floatAsRef target, float reducer)
        {
            while (objective.fv > target.fv)
            {
                objective.fv -= reducer;
                yield return null;
            }
            objective.fv = target.fv;
            yield return null;
        }

then you would need to have your maxSpeed defined as:

public floatAsRef maxSpeed = new floatAsRef();
maxSpeed.fv = 120;//for example

this is a workaround to pass value types as references into a coroutine, but its probably too complicated for your situation

1 Like

Yeah, I’m getting started, so for now I’ll leave it how it is. Thanks anyway!