How can I alter cframe values to change direction of object midway?

https://streamable.com/hcdppx

I am making a helmet that retracts and protracts over a player’s head, as you can see in the clip, it’s partially working so far but I want to move the helmet down after it goes backwards, how do I add another cframe direction to do that?
The script so far:

local TweenService = game:GetService("TweenService")

local Head = script.Parent
local Helmet = Head.Helmet

local Info = TweenInfo.new(
	0.2,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut,
	0,
	false,
	0
)


local Weld = Instance.new("Weld")
Weld.C0 = CFrame.new(0,0,0)
Weld.C1 = CFrame.new(0,0,1)

Weld.Part0 = Head
Weld.Part1 = Helmet
Weld.Parent = Head

local function CloseHelmet()
	local CloseGoal = {}
	CloseGoal.C1 = CFrame.new(0,0,0)
		local Tween = TweenService:Create(Weld,Info,CloseGoal)
	Tween:Play()
end

local function OpenHelmet()
	local OpenGoal = {}
	OpenGoal.C1 =  CFrame.new(0,0,-1) 
	local Tween = TweenService:Create(Weld,Info,OpenGoal)
	Tween:Play()
end

while true do
	CloseHelmet()
	
	wait(2)
	
	OpenHelmet()
	
	wait(2)
	

	
end

I’ve tried multiplying this line OpenGoal.C1 = CFrame.new(0,0,-1) by another cframe.new but it causes the helmet to just zoom into space. The helmet has to go backwards first THEN do down. I hope to do it via this way unless it’s truly impossible and the only way to do it is by having multiple tweens.

You could use a tween.Completed event to check when the tween has ended, then, change the goal, and create the tween again.

local function CloseHelmet()
	local CloseGoal = {}
	CloseGoal.C1 = CFrame.new(0,0,0)
	local Tween = TweenService:Create(Weld,Info,CloseGoal)
	Tween:Play()
	
	Tween.Completed:Connect(function()
		CloseGoal.C1 = CFrame.new() -- move the helmut down
            
            Tween = TweenService:Create(Weld, Info, CloseGoal)
		Tween:Play()
	end)
		

end

I’m not fully sure if it’ll work if you use the same variables, but it should work…maybe. If not, just add a 2 to the end of Tween and CloseGoal(i.e. CloseGoal2, Tween2)

1 Like

Try out this hack which rotates the C1 in a circular manner theoretically.

local TweenService = game:GetService("TweenService")

local Head = script.Parent
local Helmet = Head.Helmet

local Info = TweenInfo.new(
	0.2,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut,
	0,
	false,
	0
)


local Weld = Instance.new("Weld")
Weld.C0 = CFrame.new(0,0,0)
Weld.C1 = CFrame.new(0,0,1)

Weld.Part0 = Head
Weld.Part1 = Helmet
Weld.Parent = Head

local pivotCenter = CFrame.new(0,-0.5,0)
local pivotRadius = CFrame.new(0,0.5,0)
local weldPivotCenterValue = Instance.new("CFrameValue")
weldPivotCenterValue.Changed:Connect(function(newPivotCenter)
	Weld.C1 = newPivotCenter*pivotRadius
end)
local function CloseHelmet()
	local CloseGoal = {}
	CloseGoal.Value = pivotCenter
		local Tween = TweenService:Create(weldPivotCenterValue,Info,CloseGoal)
	Tween:Play()
end

local function OpenHelmet()
	local OpenGoal = {}
	OpenGoal.Value =  pivotCenter*CFrame.Angles(math.deg(90),0,0)
	local Tween = TweenService:Create(weldPivotCenterValue,Info,OpenGoal)
	Tween:Play()
end

while true do
	CloseHelmet()
	wait(2)
	OpenHelmet()	
	wait(2)
end
1 Like

It does the job, but could you explain the code especially all the pivotcenter stuff please?

Think of the pivot center CFrame as a part, and the pivotRadius as a CFrame offset from the part like an attachment that is above the part since it’s:

local pivotRadius = CFrame.new(0,0.5,0)

Like an attachments position property which is (0,3,0) in this image.

To get the attachments world position via CFrames we do this:

attachmentWorldCFrame = Part.CFrame * Attachment.CFrame

Notice how it’s similar to the .Changed relationship?

weldPivotCenterValue.Changed:Connect(function(newPivotCenter)
	Weld.C1 = newPivotCenter*pivotRadius
end)

Moreover it’s even similar to the jointInstance relationship within a weld’s or even Motor6D C0 or C1 assuming one or the other is equal to CFrame.new() or empty cframe that does nothing for simplicity.

study your cframes here

--Solving for Weld Part1:
weld.Part0.CFrame * weld.C0 = weld.Part1.CFrame * weld.C1 
--Assume weld.C1 = CFrame.new() unset empty
weld.Part0.CFrame * weld.C0 = weld.Part1.CFrame
--Therefore
weld.Part1.CFrame = weld.Part0.CFrame * weld.C0

Now all we are doing to get this to get a point in space relative to the rotation of the part0 CFrame. Now all we have to do is rotate this PivotCenter/Part0CFrame/AttachmentPartParent CFrame to create a cool pivot effect.

That attachments world position is the helmet.

1 Like