This is happening because the *
CFrame operation applies in the left CFrame’s space. * CFrame.Angles(0, math.rad(90), 0)
will rotate on the local or object Y axis, not the global Y axis.
It sounds like you are currently doing, even if you don’t realize it:
- Get current position
1.1 Rotate it by the current rotation (implied/automatic)
- Rotate on Y axis
What you need to be doing is:
- Get current position
- Rotate on Y axis
- Rotate by original rotation
This looks like:
local function applyOnGlobalAxis(cframe, applyCFrame)
local positionCFrame = CFrame.new(cframe.p) -- make a new CFrame at the same position as cframe
local rotationCFrame = cframe - cframe.p -- subtract the positional elements and we end up with just rotation
return positionCFrame*applyCFrame*rotationCFrame
end
-- to rotate Part on the global axis:
Part.CFrame = applyOnGlobalAxis(part.CFrame, CFrame.Angles(0, math.rad(90), 0))
If you want to rotate the part about a point or something similar, you can use the following:
local function applyAboutCFrame(baseCFrame, cframe, applyCFrame)
local relativeCFrame = baseCFrame:toObjectSpace(cframe) -- convert cframe to be relative to baseCFrame
-- baseCFrame*relativeCFrame == cframe
-- relativeCFrame is essentially a transformation we can apply to baseCFrame to get cframe
-- we can rotate or transform baseCFrame then apply that same transformation and now cframe has been moved or rotated about a point
return baseCFrame*applyCFrame*relativeCFrame
end
-- to rotate Part1 around Part2:
Part1.CFrame = applyAboutCFrame(Part2.CFrame, Part1.CFrame, CFrame.Angles(0, math.rad(90), 0))
You can even re-implement applyOnGlobalAxis
using this…
local function applyOnGlobalAxis(cframe, applyCFrame)
return applyAboutCFrame(CFrame.new(cframe.p), cframe, applyCFrame)
end
…because applyOnGlobalAxis is essentially rotating a part around an axis-aligned CFrame at its own position. CFrame.new(cframe.p)
gets us cframe
aligned to the global axis (i.e. it doesn’t have any rotation).