How to find rotation difference between 2 CFrames

Hello!

I’m working on the enemies system for my game and there’s one problem which completely destroyed me. Basically what I want to do is I want to make smooth rotation of enemy when he rotates by 180 degress and goes backwards, and to make this I want to make smooth enemy rotation based on DeltaTime value.

local function SetEnemyCFrame(EnemyObject, DeltaTime, NewCFrame: CFrame)
    --local RotSpeed = DeltaTime * EnemyObject.Speed
    local X, Y, Z = EnemyObject.CFrame:ToObjectSpace(NewCFrame):ToOrientation()
    -- X, Y, Z should be multiplied by RotSpeed, so they rotate smoothly
    -- on all devices and this is based on enemy speed
    print(math.deg(X), math.deg(Y), math.deg(Z))
    EnemyObject.CFrame = CFrame.new(NewCFrame.Position) * CFrame.Angles(X, Y, Z)
end

I found this solution while searching a TON of topics but it still work incorrectly for me. Here’s what’s going on in the actual game: https://youtu.be/ltsb3SOi-qc

CFrame of new enemy position is calculated perfectly (with rotation) and there are no problems with it, but the problem is that rotating difference between current enemy CFrame and new enemy CFrame which I am trying to calculate turns out to be incorrect every 2nd time it calculates. So I cannot make smooth rotation because I cannot calculate difference between 2 CFrames rotations to then multiply it by RotSpeed value.

And yes, I looked through 10 pages on Google, trillion devforum topics, tried to open websites with advanced mathematics, spent a whole day solving this problem and still didn’t understand what is going wrong with the calculation. So I would appreciate any help!

I think you got a weird formula.

Checkout my turret CFrame module to do it and constant speed im pretty busy cant help out much further.

Also CFrame.Angles is not orientation read the documentation.

I would try using the dot product between the two CFrame’s LookVectors. Combining that with inverse cosine would give you the angle in radians.

-- replace with your own cframes being used
local angularDifference = math.acos(cframe1.LookVector:Dot(cframe2.LookVector))

Reference if needed:
Dot product - extreme oversimplification: gives a number that indicates how similar two vectors are
Sine/cosine - trigonometry functions, using their inverses can help find angles

Also the turret controller linked in the above post is probably helpful for this situation, I personally have used it for a different purpose before.