TweenService not rotating parts properly

Hey! I’m going through a really weird thing that is happening with tweenservice.

Basically when i want to rotate a part using this line of code the part doesn’t rotate:

local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)})

Why is this weird? Because if i want to rotate a part using this line of code it works:

local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = hinge.CFrame * CFrame.Angles(math.rad(100), 0, 0)})

So the problem is that when i put 0 as angle the part doesn’t rotate. I’m making a swing door. Obviously i play the tween with tween:Play()

It’s because this:

hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)

Is not making any change in the cframe, is the same as if you make this:

1 + 0

But then why in this script it works?

local TweenService = game:GetService(“TweenService”)
local Tweeninfo = TweenInfo.new(1)

local model = script.Parent
local hinge = model.PrimaryPart
local proximityPrompt = model.Door.ProximityPrompt

local open = false

local doorOpenTween = TweenService:Create(hinge, Tweeninfo, {CFrame = hinge.CFrame * CFrame.Angles(math.rad(100), 0, 0)})
local doorCloseTween = TweenService:Create(hinge, Tweeninfo, {CFrame = hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)})

proximityPrompt.Triggered:Connect(function()
	if not open then
		open = not open
		doorOpenTween:Play()
		proximityPrompt.ActionText = "Close"
	else
		open = not open
		doorCloseTween:Play()
		proximityPrompt.ActionText = "Open"
	end
end)

You should instead change orientation, because when you’re using the * operator you’re basically adding 0 to the angle.

local tween = TweenService:Create(hinge, TweenInfo.new(time_), {Orientation = Vector3.new(0, 0, 0)})

What happens is that when multiplying a CFrame with CFrame.Angles, the angles are “added”, it only creates a CFrame with the position of the previous CFrame.

local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = CFrame.new(hinge.CFrame.Position)})

Because when you open the door the cframe changes, so then you close it, the tween will set the cframe to the origin.

Example:

local origin = hinge.CFrame + 0
local open = hinge.CFrame + 100

hinge.CFrame = open --The CFrame change
print(hinge.CFrame)
hinge.CFrame = origin --Change again
print(hinge.CFrame)

--output--
100
0

But why does it work here? it’s the same tween

local TweenService = game:GetService("TweenService")
local Tweeninfo = TweenInfo.new(1)

local model = script.Parent
local hinge = model.PrimaryPart
local proximityPrompt = model.Door.ProximityPrompt

local open = false

local doorOpenTween = TweenService:Create(hinge, Tweeninfo, {CFrame = hinge.CFrame * CFrame.Angles(math.rad(100), 0, 0)})
local doorCloseTween = TweenService:Create(hinge, Tweeninfo, {CFrame = CFrame.new(hinge.CFrame.Position)})

proximityPrompt.Triggered:Connect(function()
	if not open then
		open = not open
		doorOpenTween:Play()
		proximityPrompt.ActionText = "Close"
	else
		open = not open
		doorCloseTween:Play()
		proximityPrompt.ActionText = "Open"
	end
end)

by default, CFrame.new gives 0 angle in all directions.

Ok but you didn’t answer the question, i just want to understand

What you want is for it to have 0 orientation in all its axes, right? CFrame.new(Position) creates a CFrame with that position, but with 0 orientation in all 3 axes.

what you are doing is adding 0 degrees to the previous CFrame, not making it have 0 degrees.

Ok ok, i understood your point.

Now can you please explaing this?

Not working:

local functions = require(game.ServerScriptService.Functions)

local model = script.Parent
local hinge = model.PrimaryPart
local proximityPrompt = model.Door.ProximityPrompt

local open = script.Parent.Open

proximityPrompt.Triggered:Connect(function()
    if not open.Value then
        open.Value = not open.Value
        functions:OpenDoor(hinge, 1, 100)
    else
        open.Value = not open.Value
        functions:CloseDoor(hinge, 1)
    end
end)

ModuleScript:

local TweenService = game:GetService("TweenService")

local functions = {}

function functions:OpenDoor(hinge, time_, angle)
    local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = hinge.CFrame * CFrame.Angles(math.rad(angle), 0, 0)})
    
    hinge.Parent.Open.Value = true
    hinge.Parent.Door.ProximityPrompt.ActionText = "Close"
    
    tween:Play()
    print("Opening")
end

function functions:CloseDoor(hinge, time_)
    local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)})
    
    hinge.Parent.Open.Value = false
    hinge.Parent.Door.ProximityPrompt.ActionText = "Open"
    
    tween:Play()
    print("Closing")
end

return functions

Working:

local TweenService = game:GetService("TweenService")
local Tweeninfo = TweenInfo.new(1)

local model = script.Parent
local hinge = model.PrimaryPart
local proximityPrompt = model.Door.ProximityPrompt

local open = false

local doorOpenTween = TweenService:Create(hinge, Tweeninfo, {CFrame = hinge.CFrame * CFrame.Angles(math.rad(100), 0, 0)})
local doorCloseTween = TweenService:Create(hinge, Tweeninfo, {CFrame = hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)})

proximityPrompt.Triggered:Connect(function()
	if not open then
		open = not open
		doorOpenTween:Play()
	else
		open = not open
		doorCloseTween:Play()
	end
end)

I think you dont understand the variables.

hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0)

This is the same as just this:

hinge.CFrame

Because:

local rotate = 1 --This is the hinger.CFrame
rotate + 0 --This is the math.rad(0)

This is the same as just this:

rotate

In the door code the CFrames stores in the tweens

local doorOpenTween = hinge.CFrame * CFrame.Angles(math.rad(100), 0, 0)
local doorCloseTween = hinge.CFrame * CFrame.Angles(math.rad(0), 0, 0) --this is the same as just this hinge.CFrame

--The origin CFrame is the doorCloseTween  because is the actual hinge CFrame

--Open the door:
hinge.CFrame = doorOpenTween 
--Now the actual CFrame is the "doorOpenTween"  value
--Close the door:
hinge.CFrame = doorCloseTween
--Now the actual CFrame change to the origin(doorCloseTween value)

The moduleScript CloseDoor code is using the actual CFrame(actual = 100, actual + 0 = actual) so the hinge is not doing anything.

Oh ok this was the part i was missing thanks

you are passing the current frame of the door, change that line to this

local tween = TweenService:Create(hinge, TweenInfo.new(time_), {CFrame = CFrame.new(hinge.CFrame.Position)})