MovementUtils.cpp : 672
StartingOrient should be on the right side of the quaternion multiplication operator because AngluarVelocityDegree is based on the world coordinate ssystem. according to the quaternion multiplication operator comment, C = A * B, first apply B then A( right first, then left)
FQuat UMovementUtils::ApplyAngularVelocityToQuat(const FQuat& StartingOrient, const FVector& AngularVelocityDegrees, float DeltaSeconds)
{
if (!AngularVelocityDegrees.IsZero())
{
const FQuat TargetOrientQuat = StartingOrient * FQuat::MakeFromRotationVector(FMath::DegreesToRadians(AngularVelocityDegrees) * DeltaSeconds);
return TargetOrientQuat;
}
return StartingOrient;
}
Hello! I’ve double checked with the folks working on Mover. AngularVelocityDegrees is intended to be provided in the pawn’s coordinate space, so for example Yaw=90 means rotation around the pawn’s local Z-up axis and not the world’s Z-up axis. The existing callsites of that function, like
UMovementUtils::ApplyAngularVelocityToRotator(StartingOrient, ProposedMove.AngularVelocityDegrees, DeltaSeconds);provide it in the pawn’s local space (“along rotation axis” implying in the pawn’s coordinate space):
// Angular velocity in degrees per second. Direction points along rotation axis.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover)
FVector AngularVelocityDegrees = FVector::ZeroVector;
We can see the usefulness of applying a world angular velocity, so discussing internally whether to add another utils function. On your end, please just implement your own utility function for now if you need to apply a world space oriented angular velocity.
Thank you for pointing out the inconsistency between ProposedMove.LinearVelocity being expected in world space and AngularVelocityDegrees in local space. I took that back to the devs and after a quick discussion, we agree that that’s confusing.
I logged an internal task to make this consistent. In a future engine version, we plan to:
- Deprecate FProposedMove.AngularVelocityDegrees and replace it with FProposedMove.WorldAngularVelocityDegrees. Deprecating the old variable is primarily to not silently change behavior of existing game project code.
- Deprecate UMovementUtils::ApplyAngularVelocityToQuat, ApplyAngularVelocity and similar variantsand replace them with UMovementUtils::ApplyWorldAngularVelocityToQuat.
Basically, in a future engine release we plan to make angular velocity world space and be clear about that. We’re not sure about a timeline for it yet, but when we do, the release notes and deprecation warnings should make things clear. Thanks for bringing this to our attention.
No problem! I’ll close this case.
Thanks for your reply. I also double checked engine source code, and I found I was misled by
AnimRootMotionLayeredMove.cpp : 94
if (DeltaSeconds > UE_KINDA_SMALL_NUMBER)
{
OutProposedMove.LinearVelocity = WorldSpaceRootMotion.GetTranslation() / DeltaSeconds;
OutProposedMove.AngularVelocityDegrees = FMath::RadiansToDegrees(WorldSpaceRootMotion.GetRotation().ToRotationVector() / DeltaSeconds);
}
I saw that AngularVelocityDegrees is obtained from the WorldSpaceRootMotion. Is it an engine mistake or have I misunderstood the coordinate system here?
In addition, I think you should directly add the description of the coordinate system in AngularVelocityDegrees’s comment. Because LinearVelocity is based on world space, AngularVelocity based on local space is not consistent behavior and contrary to human intuition.
This is wonderful! Thanks for your time.