Suggestion: LateFixedUpdate()

I’m looking how to change velocity of an object after it’s moved, but before the next FixedUpdate.

And I’m seeing I’m not alone looking to do that with multiple posts about just this.

Seems like it’s fairly simple to do. Just do another FixedUpdate, but execute it after the physics cycle.

Im certain it would get some use.

You can use any Updates for this which comes after the “internal physics update”:
https://docs.unity3d.com/Manual/ExecutionOrder.html

You also can define your own PlayerLoop, so you can have whatever update you want:
https://docs.unity3d.com/ScriptReference/LowLevel.PlayerLoop.html

Although the examples from Unity is non-existent AFAIK, but you can find some examples if you search the google.

2 Likes

Not reliably, because FixedUpdate() is called a variable number of times between them.

It looks like using a Coroutine which yields on WaitForFixedUpdate() would be a close equivalent to a LateFixedUpdate() method. It could be started in OnEnable() and stopped in OnDisable().

Edit: Personally, rather than adding more magic names, I’d lean towards removing some and replacing them with events we can listen for. Or better yet, orderable queues we can add objects to. I definitely agree Unity could be improved in this area in general. Edit again: Haha, yeah, just like that PlayerLoop you mentioned sounds like it can give us. :smile:

Yeah, thinking through again, you’re right. On the occasion when multiple FixedUpdate is called between updates, that can be a problem.
But you can make it work if you add up the added velocities you added through the previous FixedUpdates and change the sum of them in the Update afterward. Since there is no render between these calls, it wouldn’t affect anything. Although it is not out of the box, that’s true.

It would effect the resulting position of the object. For instance if I was calculating the position of an object which was turning it would result in understeer, because it would use an older, un-turned velocity for more physics steps. It would end up pointed at the correct angle from an incorrect position.

I think something like this (not real C#, pseudocode-alert):

class Foo
{
    Vector3 sumVelocityAdded = Vector3.zero;

    void FixedUpdate()
    {
        WhateverObject.velocity += VelocityToBeAdded;
        sumVelocityAdded += VelocityToBeAdded;
    }
    void LateUpdate()
    {
        WhateverObject.velocity -= sumVelocityAdded;
        sumVelocityAdded = Vector3.zero;
    }
}

Edit: yes, this is actually wrong.

I don’t see how this would end up with less velocity and understeering. But it’s Sunday, I maybe can’t think straight, so I may be completely wrong.

What I’m not sure of is whether there’s any difference between doing the calculation “before the update” (in FixedUpdate) vs “after the update”. Either way you’re calculating new values for the next physics step based on the results of the last one.

What’s the use case here, @Not_Sure ? Do you need it to go before the transforms are updated or collision events are raised, or something?

And obviously it is more simple to handle all in the FixedUpdate:

class Foo
{
    Vector3 velocityAddedLastFrame;
    void FixedUpdate()
    {
        WhateverObject.velocity += (VelocityToBeAdded - velocityAddedLastFrame);
        velocityAddedLastFrame = VelocityToBeAdded;
    }
}

Also need to look out for floating point error-accumulation if any and if it can be a problem.

Could be we’re talking about different things.

Take five steps forward, then turn 50 degrees to the right.

Compare that to taking one step forward and turning 10 degrees to the right, 5 times.

You will get different results to your position depending on when you integrate your velocity changes relative to performing the movement.

FixedUpdate always runs before physics update and the goal is to temporarily give a certain velocity to an object and after the physics calculated, take it away, so next frame it can be changed from the base line velocity (or kind of a pulse per frame). So I don’t understand this at all. We do not talk about one big step versus many small steps here, we are talking about pulse-like velocity changes.

Maybe it’s more clear with this thread: https://discussions.unity.com/t/839331

Edit: I told you, I’m an idiot today. I see what you’re trying to say. :smile: I said the same and still presented the wrong solution. Scratch the LateUpdate-handling situation.

That would have side effects, such as messing with the resulting force of any collisions. But more fundamentally, we don’t even know what problem is being solved here.

1 Like

Okay, what I’m looking to do is make a rigidbody FPS controller where the movement is independent of the rigidbody’s velocity.

I want to be able to do things like get hit with a rocket and knock the player around while at the same time being able to apply movement independent of the velocity.

Every tutorial I’ve seen makes it so that applying movement cancels out whatever velocity you have.

This shouldn’t require any extra work.

To knock back the player, add impulse.
At the same time you can still control rigidbody velocity however you want.
The difference is instead of setting the velocity based on input , you add it.
Basically, would be something like this:

float xMove = ///get gamepad X Axis, scale, etc
float yMove = ///get gamepad Y Axis, scale, etc.

var currentVel = rigidbody.velocity;
var nextVel = currentVel + xMove * transform.right * Time.deltaTime + yMove * transform.forward *Time.deltaTime;
rigidbody.velocity = nextVel;

You’ll need to implement sanity checks so the player does not reach the lightspeed, but that’ the general principle. This can be done within Update, FixedUpdate, doesn’t matter. You also don’t need LateFixedUpdate.

1 Like

No idea if it’ll work, but if you just change rigidbody.position does that change the position without modifying the velocity?

Otherwise, one approach is to independently track the velocity contribution coming from player input, use that to calculate the non-input component of the velocity, split them, do your thing, and re-combine them each tick. Which is hacky and has lots of edge cases. For instance, if a player is walking into a wall you’re going to have to clip the velocity contribution accordingly.

Another approach would be to make the controller kinematic and calculate and apply all of your own forces. Since you could track movement and external forces separately that might be easier and have fewer edge cases. It’d also give you more explicit control over things, so while it sounds daunting it could end up being less work over the whole of the project. Not sure how many or what kind of edge cases you might run into, though.

Edit: I did think of straight up adding velocity as @neginfinity suggests. I’ve done this before, though, and couldn’t make it feel anything other than “sloppy” and/or “slidey”. Mileage may vary, though, and maybe the feel will work for your game. Definitely a simple approach if it can work.

Last time I checked, the part of the PlayerLoop that’s supposed to allow you to run stuff in the fixed timestep instead of the normal one just straight up didn’t work. That might have been fixed, or I might’ve been doing things wrong, since they’re not documenting it I’m not sure.

1 Like

Well, what you’d get is similar to player movement in original Doom. Where you were rollerskating thorugh the level at a speed of a rocket.

This is not a kind of movement you usually see for movement these days, but it will work if you’re implementing a hovercraft, hoverboard, or something similar.

1 Like

You could check if manually setting script execution order affects FixedUpdate. (I haven’t tried it)

If so, you could create a separate script which you have set to be called first. In both Update and FixedUpdate, either one of which will be called first after a physics update but before the next frame is rendered, you then do whatever physics change you need to do after the last physics update. Just set a static bool on any object that needs this after physics update change, and unset it on this separate script that gets called first to say that you’ve done the change.

Slide and side drift can be handled by getting the x axis velocity and applying a counterforce impulse, which can be multiplied to get less or zero drift.

It does. I’m using this to fire an “OnLateFixedUpdate” from a singleton with a very large execution order value to implement interpolation for custom FixedUpdate movement. The inverse can be used to implement an “OnEarlyFixedUpdate” event.

1 Like

yield return new WaitForFixedUpdate();

1 Like