I’ve created a script to interpolate a part’s angles revolving fully around a circle in a loop (counter clockwise), however I don’t know how/why the CFrame angles are moving the position as well. It’s probably to do with how I’m handling the calculation of standard position, as I haven’t found a way to retrieve that successfully as tuple of 3 values.

``````local part = script.Parent
local TweenService = game:GetService("TweenService")

local function rotationFromCFrame(cframe)
--[[ Returns a tuple containing the angles from any cframe passed. ]]

-- why not `local standardPos = CFrame:ToEulerAnglesXYZ (CFrame.Angles(part.CFrame))`?  Argument 3 missing or nil for some reason appears even if (0,0,0)
local components = { cframe:components() } -- put into array
return components[4], components[5], components[6]
end

------- Variables
local standardPos = CFrame.Angles( rotationFromCFrame(part.CFrame) )
print(standardPos)

local rotations = {
math.pi/2,
math.pi,
(3 * math.pi)/4,
}

local function tweenRot(part, cframe, duration)
--[[ Tween wrapper that rotates a part's rotation from passed args. ]]

local goal -- declare. should never be nil
if cframe == 'standardPosition' then
goal = {
CFrame = standardPos
}
else
goal = {
CFrame = part.CFrame * cframe
}
end

local tweenInfo = TweenInfo.new(
duration,
Enum.EasingStyle.Sine,
Enum.EasingDirection.Out,
0,
false,
0
)

local tween = TweenService:Create(part, tweenInfo, goal)
tween:Play()

local debugvars = "goal: "
for i,v in pairs(goal) do
debugvars = debugvars .. tostring(v) .. ', '
end
print(debugvars)
end

------- Main
repeat wait()
for index=1, #rotations  do
wait(3)
tweenRot(part, CFrame.Angles(0,rotations[index],0), 1)

print('Index CFrame:\t i=' .. index .. ' | ' .. tostring( rotations[index]) )
print('Part CFrame:\t i=' .. index .. ' | ' .. tostring( rotationFromCFrame(part.CFrame) ) .. '\n')
end
wait(3)

tweenRot(part, 'standardPosition', 1) -- reset to standard pos
until part == nil``````
1 Like

You are setting the `CFrame` of the part as a `CFrame` returned by `CFrame.Angles()`, which means the `Position` of that `CFrame` is `Vector3.new(0, 0, 0)`. If you only want to set the rotation as the rotation of standardPos and not change the position, try replacing

``````CFrame = standardPos
``````

with

``CFrame = CFrame.new(part.Position)*standardPos``
1 Like

Thank you. That fixes one problem, however the part still doesn’t rotate correctly purely around the y axis, and nor in one direction

I think you may have misunderstood how `CFrame:ToEulerAnglesXYZ` works, because you had this in a comment

``````local standardPos = CFrame:ToEulerAnglesXYZ (CFrame.Angles(part.CFrame))
``````

To get the angles from the `CFrame` of the part, you can simply do this.

``````local x, y, z = part.CFrame:ToEulerAnglesXYZ()
``````

`ToEulerAnglesXYZ` is a method, not a constructor.

Is the 3rd element in your rotations array supposed to be `(3 * math.pi)/2` ?