Calling :ApplyAngularImpulse() on loop causes unexpected behaviour

Create two regular, unanchored parts and float them setting gravity to 0. In one create a Torque constraint with a small torque value, say 0,3,0. Then in the other insert this code:

game:GetService("RunService").Stepped:Connect(function(_,dt)
	script.Parent:ApplyAngularImpulse(Vector3.new(0,3*dt,0))
end)

As Angular Impulse is equal to torque * time, applying Angular Impulse per second is just equal to torque (In SI units, Nm*s/s ->Nm), minus some very small discrepenancies due to being applied in larger time steps than the constraint. Instead of identical results the part using the angular impulse moves slowly and in stutters, shown below with the Impulse in blue, left, and the constraint in red, right.

6 Likes

Update: You can further show that this is an issue specifically with :ApplyAngularImpulse() by using :ApplyImpulseAtPosition() to create a torque instead, which works as expected:

Edit: I intially made a mistake with this update and did not include the *dt. ApplyAngularImpulseAtPosition behaves in the same manner to AngularImpulse.

game:GetService("RunService").Stepped:Connect(function(_,dt)
	script.Parent:ApplyImpulseAtPosition(Vector3.new(0,0,3*dt), script.Parent.Position+Vector3.new(0.5,0,0))
	script.Parent:ApplyImpulseAtPosition(Vector3.new(0,0,-3*dt), script.Parent.Position+Vector3.new(-0.5,0,0))
end)
1 Like

Thanks for the report! We’ll follow up when we have an update for you.

2 Likes

It appears the issue has something to do with ApplyImpulse not waking the part. After enabling highlight awake parts, it appears the part with ApplyImpulse is flickering.

After some time, the part eventually picks up speed and no longer is a sleeping part, and it functions as intended.

I think this could simply be solved by making parts stay awake for a minimum amount of time before going to sleep after ApplyImpulse is called.

3 Likes

Hi!

As @SubtotalAnt8185 pointed out, the part is intermittently falling asleep, which is causing the stuttering that you observed. The Stepped event fires once per frame, but we may perform a different number of physics timesteps between each frame. So, applying angular impulses is not exactly equivalent to applying a constant torque. Moreover, the angular velocity resulting from these low torques is very close to the sleep threshold, so stuttering is more likely to occur.

To get the most consistent behavior, I recommend applying a constant torque. This will ensure that the parts will sleep/wake in a more predictable way.

1 Like