I need to know if my character is turning left or right, based on a previous CFrame and a current CFrame.
I have tried using ToEulerAnglesXYZ() and ToOrientation() on both the current and previous CFrame in order to isolate the Y axes and compare their rotation values. Something like, “if the current one’s Y rotation is more than the previous one’s, you are turning left.”
The issue is that at some point, the Y axis that was more than the other one eventually hits 180, which then after flips to -1, and the first Y axis is no longer greater than the other one for a brief moment. This registers as going the opposite direction of what you were going.
Is there a way I can compare the rotations of two Y axes in order to get the turn direction without this issue?
I think something like math.atan2 on the X/Z components of the lookVector could give you what your looking for. math.atan2(cf.LookVector.X,cf.LookVector.Z))
To convert to degrees, use math.deg.
Just to add onto this because I didn’t fully explain how you could use this, only really answered how to retrieve the degrees, but you could grab both the current and previous lookVector, subtract one from the other, and then use this math.atan2 and it will give you the angle between them and that can be used to determine left/right.
For this method, you will need to compare at least two CFrames, but it will give you their relative direction and the angle difference between them:
local V3_101 = Vector3.new(1,0,1) --Constant Vector to isolate direction.
local function determine_direction(next_CFrame, prev_CFrame) --Define your CFrames however you'd like.
--First, determine the flat directions of the two CFrames.
local new_direction = (next_CFrame.LookVector * V3_101).Unit
local old_direction = (prev_CFrame.LookVector * V3_101).Unit
--This is the difference in radians between the two directions.
--It is ALWAYS positive, so this does not tell you the direction, but it can be nice to know.
local absolute_angle = math.acos(old_direction:Dot(new_direction))
--This value is what tells you the direction.
--NEGATIVE = next direction is to the RIGHT of the old one.
--POSITIVE = next direction is to the LEFT of the old one.
local y_cross = old_direction:Cross(new_direction).Unit.Y
return y_cross, absolute_angle
end
This should get you the results you need. I ripped it from some of my old code and may have misunderstood my own implementation, so the direction-sign correlation of y_cross might be reversed, but the logic should be correct.
All in all, though, I don’t personally know all of the mathematics behind this. I adapted it from a StackExchange post back when I needed it.
1 Like