IEnumerator with Physics

Hey All,

I’m trying to Add Force to a physics object via a coroutine. However, I’m getting inconsistent force added, so must be doing something wrong. *Note: I use a 3rd party character controller so I call AddMomentum() rather than rb.AddForce(). But it does a very similar function.

Why doesn’t this code add the same amount of force every time? I’m calling it once from within the FixedUpdate loop. Appreciate any advice!

Thx!

IEnumerator MomentumAdder(Vector3 _dir, float _duration, AnimationCurve _curve)
        {
            // Convert duration of momentum to be added into 0-1 so we can apply it against the animation curve
            float step = 1 / _duration;
            float curveTime = 0f;
            float durationCountUp = 0; // We count this up in our while loop each fixedupdate

            // while within duration time           
            while (durationCountUp < _duration)
            {
                // Adjust the Vector3 force direction based on curve
                _dir *= _curve.Evaluate(curveTime);
                             
                // Countup the duration adjusted for fixedDelta time (as we want this to run on the physics clock)
                durationCountUp += Time.fixedDeltaTime;

                // Get the next place on the curve based on where we are in the duration
                curveTime += durationCountUp * step;

                // Add Momentum
                AddMomentum(_dir);

                // Yield until the next physics step
                yield return new WaitForFixedUpdate();
            }
        }

What does “AddMomentum” do?

What do you mean by this? How are you calling it? Are you using StartCoroutine?

You’re pulling some values out of a curve. Print them out in Debug.Log, drag them into a spreadsheet, see if they’re the same each time. At least first identify that your portion of the data truly is as stable and predictable as you think it is. Once you know that, then you can look further.

Yes, calling StartCoroutine but with a bool flag so when it meets the criteria it won’t call it every Fixed Update, only once.

Appreciate the advice. I pulled the logs from two scenarios. a) where no force appears to be added and b) where correct amount of force appears to be added. The coroutine loop runs exactly 31 loops every time based on my fixed step settings and _duration input. My duration and curve time are consistent for each loop too. However, I also checked velocity on each loop and it’s not consistent. It does try to add velocity in both scenarios but varying amounts.

Based on that, it seems like it could be an issue with the AddMomentum function in the 3rd party controller or something unrelated to the coroutine then, right? I just wanted to check I wasn’t doing something silly with the coroutine itself.

Well that’s the next stop in the data flow pipeline… construct an experiment to verify the behavior is as you expect.

2 Likes