I am trying to rotate a character using AngularVelocity
so that it matches the rotation of motion extracted from an animation. On each frame I am getting the current motion (position and rotation) of the animation and finding the difference from the motion last frame. This delta is a CFrame and doing RootPart.CFrame *= Delta
every frame will move the character to the correct position to match the animation. But I’m trying to move the character physically, hence the need to calculate velocities.
Calculating the linear velocity works as expected but it looks like the angular velocity works a bit differently.
RunService.Stepped:Connect(function(_, dt)
local Animation = Track.Animation
local Motion = GetCFrameFromCurves(Animation.Position, Animation.Rotation, Track.TimePosition)
local Delta = LastMotion:ToObjectSpace(Motion)
LastMotion = Motion
-- RootPart.CFrame * Delta is where the character should end up.
-- Make motion relative to character root part. This is for translation.
local MoveMotion = RootPart.CFrame:VectorToWorldSpace(Delta.Position)
-- Translate root part.
-- LinearVelocity constraint is in world space.
local PlaneMotion = Vector2.new(MoveMotion.Z, MoveMotion.X)
LinearVelocity.PlaneVelocity = PlaneMotion / dt -- This is correct.
-- Rotate root part.
-- AngularVelocity constraint is in local space (Attachment0).
local DeltaAngles = Vector3.new( Delta.Rotation:ToEulerAngles(Enum.RotationOrder.XYZ) )
AngularVelocity.AngularVelocity = DeltaAngles / dt -- This does not work.
end)
You can see in the video that the angular velocity is not correct on the character that is physically moved.
Interestingly though, if I multiply the angular velocity by this random constant, which I narrowed in on using trial and error, the angular velocity is correct (even with variable dt).
-- Multiplying by this random constant produces the correct result
-- What is the significance of this number?
AngularVelocity.AngularVelocity = DeltaAngles / dt * 1.425