Weld tweening not working as intended

Does it have the same issue or not?
Can you also show us the output of the welds and their C1’s? Please?

2 Likes

I might be too tired for this stuff, but what do I do? :rofl:

Maybe tostring()?

1 Like

obrazek

1 Like

Errr… a bit of an issue here…

I made a function previously which aids in printing CFrames, just use this:

local function PrintCFrame(CF:CFrame)
	local x,y,z = CF:ToOrientation()
	local pos = CF.Position
	if pos.Magnitude == 0 then
		return "Rotation (XYZ): "..math.round(x*10)/10 ..math.round(y*10)/10 ..math.round(z*10)/10
	else
		return "Position (XYZ): "..math.round(pos.X*10)/10 ..math.round(pos.Y*10)/10 ..math.round(pos.Z*10)/10,"\n \n Rotation (XYZ): "..math.round(x*10)/10 ..math.round(y*10)/10 ..math.round(z*10)/10
	end
end

Kind of like:

print(PrintCFrame(upWeldC1))
1 Like

nvm you can actually just remove the string before it (the text that i put there) and just print the value, it then works… before tweening, it prints this:


top one is upweld, bottom one is downweld

after tweening (pressed both down & up buttons) it prints this:
(prints it twice for some reason [like 4 time] ig idk why, but we can see here that its indeed still the same value)

1 Like

I would suggest using the function I sent. This is hard to understand just like that.

1 Like

Well it’s visible that before tweening, the values are different, after tweening (or basically after the functions), its the same

1 Like

Can you send me the entire code for this?

2 Likes

LocalScript

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local DriveSeat = script.Parent
local player = Players.LocalPlayer

RS.Remotes.ToggleRoadMaintenanceUI.OnClientEvent:Connect(function(car, argument)
	local RoadMaintenanceUI = player.PlayerGui:WaitForChild("RoadMaintenance").Frames.DOTSnowPlow
	
	if argument == "sit" then
		if RoadMaintenanceUI then
			RoadMaintenanceUI.Visible = true
			
			for i, v in pairs(RoadMaintenanceUI.Buttons:GetChildren()) do
				if v:IsA("Frame") then
					v.TextButton.MouseButton1Click:Connect(function()
						script:WaitForChild("ClickSound"):Play()
						
						if v.Name == "SaltOff" then
							v.UIStroke.Color = Color3.fromRGB(255, 170, 0)
							RoadMaintenanceUI.Buttons.SaltOn.UIStroke.Color = Color3.fromRGB(27, 27, 27)
							
							RS.Remotes.FunctionsRoadMaintenanceUI:FireServer(car)
						elseif v.Name == "SaltOn" then
							v.UIStroke.Color = Color3.fromRGB(255, 170, 0)
							RoadMaintenanceUI.Buttons.SaltOff.UIStroke.Color = Color3.fromRGB(27, 27, 27)	
							
							RS.Remotes.FunctionsRoadMaintenanceUI:FireServer(car)
						elseif v.Name == "SnowDown" then
							v.UIStroke.Color = Color3.fromRGB(255, 170, 0)
							RoadMaintenanceUI.Buttons.SnowUp.UIStroke.Color = Color3.fromRGB(27, 27, 27)	
							
							RS.Remotes.FunctionsRoadMaintenanceUI:FireServer(car)
						elseif v.Name == "SnowUp" then
							v.UIStroke.Color = Color3.fromRGB(255, 170, 0)
							RoadMaintenanceUI.Buttons.SnowDown.UIStroke.Color = Color3.fromRGB(27, 27, 27)	
							
							RS.Remotes.FunctionsRoadMaintenanceUI:FireServer(car)
						end
					end)
				end
			end
		end
	elseif argument == "leave" then
		if RoadMaintenanceUI then
			RoadMaintenanceUI.Visible = false
			RoadMaintenanceUI.Buttons.SaltOn.UIStroke.Color = Color3.fromRGB(27, 27, 27)
			RoadMaintenanceUI.Buttons.SaltOff.UIStroke.Color = Color3.fromRGB(255, 170, 0)
			RoadMaintenanceUI.Buttons.SnowDown.UIStroke.Color = Color3.fromRGB(27, 27, 27)
			RoadMaintenanceUI.Buttons.SnowUp.UIStroke.Color = Color3.fromRGB(255, 170, 0)
		end
	end
end)

ServerScript

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("FunctionsRoadMaintenanceUI")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

RemoteEvent.OnServerEvent:Connect(function(player, car)
	local plowUpPart = car:WaitForChild("Body").SnowPlow.UP
	local plowDownPart = car:WaitForChild("Body").SnowPlow.Down

	local upWeld
	local upWeldC1,downWeldC1
	for _, weld in pairs(car:WaitForChild("DriveSeat"):GetChildren()) do
		if weld.Name == "UP" and weld.Active then
			upWeld = weld
			upWeldC1 = weld.C1
		elseif weld.Name == "Down" and weld.Active then
			downWeldC1 = weld.C1
		end
	end

	if not upWeld or not downWeldC1 then
		return
	end
	
	print(upWeldC1)
	print(downWeldC1)

	local tweenInfo = TweenInfo.new(2.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
	
	local function playHydraulicsSound()
		local hydraulicsSound = Instance.new("Sound")
		hydraulicsSound.Parent = plowUpPart
		hydraulicsSound.SoundId = "rbxassetid://9114854344"
		hydraulicsSound.Volume = 0.5
		hydraulicsSound:Play()
		
		hydraulicsSound.Ended:Connect(function()
			hydraulicsSound:Destroy()
		end)
	end
	
	local goal

	if plowUpPart:GetAttribute("plowPosition") == "Up" then
		goal = {C1 = downWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Down")
	elseif plowUpPart:GetAttribute("plowPosition") == "Down" then
		goal = {C1 = upWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Up")
	end
	
	local tween = TweenService:Create(upWeld, tweenInfo, goal)
	tween:Play()
	playHydraulicsSound()
	
	print(upWeldC1)
	print(downWeldC1)
end)
1 Like

Oh, my god… I am stupid. Okay, it’s been a long day and it’s 2:30 AM for me right now and I haven’t had much sleep in a few days…

Okay so the issue is that as you tween the weld right, it changed the C1 of the weld. Which means when you try setting it again it won’t work. The ONLY fix for this is to store the CFrame value ORRR:

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("FunctionsRoadMaintenanceUI")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

local upWeld
local upWeldC1,downWeldC1

RemoteEvent.OnServerEvent:Connect(function(player, car)
	local plowUpPart = car:WaitForChild("Body").SnowPlow.UP
	local plowDownPart = car:WaitForChild("Body").SnowPlow.Down

	if not upWeldC1 or not downWeldC1 then
		for _, weld in pairs(car:WaitForChild("DriveSeat"):GetChildren()) do
			if weld.Name == "UP" and weld.Active then
				upWeld = weld
				upWeldC1 = weld.C1
			elseif weld.Name == "Down" and weld.Active then
				downWeldC1 = weld.C1
			end
		end
	end

	for _, weld in pairs(car:WaitForChild("DriveSeat"):GetChildren()) do
		if weld.Name == "UP" and weld.Active then
			upWeld = weld
		end
	end
	if not upWeld or not downWeldC1 then
		return
	end
	
	print(upWeldC1)
	print(downWeldC1)

	local tweenInfo = TweenInfo.new(2.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
	
	local function playHydraulicsSound()
		local hydraulicsSound = Instance.new("Sound")
		hydraulicsSound.Parent = plowUpPart
		hydraulicsSound.SoundId = "rbxassetid://9114854344"
		hydraulicsSound.Volume = 0.5
		hydraulicsSound:Play()
		
		hydraulicsSound.Ended:Connect(function()
			hydraulicsSound:Destroy()
		end)
	end
	
	local goal

	if plowUpPart:GetAttribute("plowPosition") == "Up" then
		goal = {C1 = downWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Down")
	elseif plowUpPart:GetAttribute("plowPosition") == "Down" then
		goal = {C1 = upWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Up")
	end
	
	local tween = TweenService:Create(upWeld, tweenInfo, goal)
	tween:Play()
	playHydraulicsSound()
	
	print(upWeldC1)
	print(downWeldC1)
end)
2 Likes

Thanks again for the reply, but now, it doesn’t even tween down :sweat_smile:

1 Like

Alright, so I got an even better damn idea.

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("FunctionsRoadMaintenanceUI")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

RemoteEvent.OnServerEvent:Connect(function(player, car)
	local plowUpPart = car:WaitForChild("Body").SnowPlow.UP
	local plowDownPart = car:WaitForChild("Body").SnowPlow.Down

	local upWeld
	local upWeldC1,downWeldC1
	for _, weld in pairs(car:WaitForChild("DriveSeat"):GetChildren()) do
		if weld.Name == "UP" and weld.Active then
			upWeld = weld
			upWeldC1 = weld:GetAttribute("UpC1")
		elseif weld.Name == "Down" and weld.Active then
			downWeldC1 = weld.C1
		end
	end

	if not upWeld or not downWeldC1 then
		return
	end

	print(upWeldC1)
	print(downWeldC1)

	local tweenInfo = TweenInfo.new(2.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)

	local function playHydraulicsSound()
		local hydraulicsSound = Instance.new("Sound")
		hydraulicsSound.Parent = plowUpPart
		hydraulicsSound.SoundId = "rbxassetid://9114854344"
		hydraulicsSound.Volume = 0.5
		hydraulicsSound:Play()

		hydraulicsSound.Ended:Connect(function()
			hydraulicsSound:Destroy()
		end)
	end

	local goal

	if plowUpPart:GetAttribute("plowPosition") == "Up" then
		goal = {C1 = downWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Down")
	elseif plowUpPart:GetAttribute("plowPosition") == "Down" then
		goal = {C1 = upWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Up")
	end

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

	print(upWeldC1)
	print(downWeldC1)
end)

The ONLY thing you need to do, with this code is to have an attribute named “UpC1” in the upWeld weld. You do it in studio.

1 Like

what should I set the attribute to?

1 Like

Almost forgot to tell you that.

Set the attribute named “UpC1” in the upweld instance to the C1 of that weld. Ensure it’s a CFrame attribute.

2 Likes

I can’t set it from studio, only from a script (:SetAttribute), because the welds get made from a welding script, not manually from studio

1 Like

Then set it when it gets made?

Try this.

local RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("FunctionsRoadMaintenanceUI")
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")

RemoteEvent.OnServerEvent:Connect(function(player, car)
	local plowUpPart = car:WaitForChild("Body").SnowPlow.UP
	local plowDownPart = car:WaitForChild("Body").SnowPlow.Down

	local upWeld
	local upWeldC1,downWeldC1
	for _, weld in pairs(car:WaitForChild("DriveSeat"):GetChildren()) do
		if weld.Name == "UP" and weld.Active then
			upWeld = weld
			if not upWeld:GetAttribute("UpC1") then
				upWeldC1 = weld:SetAttribute("UpC1",weld.C1)
			end
			upWeldC1 = weld:GetAttribute("UpC1")
		elseif weld.Name == "Down" and weld.Active then
			downWeldC1 = weld.C1
		end
	end

	if not upWeld or not downWeldC1 then
		return
	end

	print(upWeldC1)
	print(downWeldC1)

	local tweenInfo = TweenInfo.new(2.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)

	local function playHydraulicsSound()
		local hydraulicsSound = Instance.new("Sound")
		hydraulicsSound.Parent = plowUpPart
		hydraulicsSound.SoundId = "rbxassetid://9114854344"
		hydraulicsSound.Volume = 0.5
		hydraulicsSound:Play()

		hydraulicsSound.Ended:Connect(function()
			hydraulicsSound:Destroy()
		end)
	end

	local goal

	if plowUpPart:GetAttribute("plowPosition") == "Up" then
		goal = {C1 = downWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Down")
	elseif plowUpPart:GetAttribute("plowPosition") == "Down" then
		goal = {C1 = upWeldC1}
		plowUpPart:SetAttribute("plowPosition", "Up")
	end

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

	print(upWeldC1)
	print(downWeldC1)
end)
1 Like

Not really sure what’s wrong, as it seems nice. However, it still doesn’t tween at all. I tried fixing it with GPT as well, but it didn’t help either. I guess imma just leave it for tomorrow or idk, because I’m kinda tired too :sweat_smile:.

1 Like

When I tween I’ve never set the tween to something other than it’s value.

For example set the goals to (for example) make the upWeld C1 Vector3 something like (0,0,2) and the downWeld Vector3 (0,0,0).

If you’re still having issues I can send code tonight.

1 Like

Here’s what I used with a ProximityPrompt to open a door in a rotating observatory dome. The dome spins so the tween couldn’t just be an Anchored Part’s CFrame. Basically all you need from here is the way the weld is tweened.

I only use the one check for the open or closed condition (the ProximityPrompt name, but yours can be your Attribute).

As you can see the Weld.C0 is the only thing changed. I set the actual Position and Orientation of the weld using the Weld.C1 making it much easier to start with a C0 of 0,0,0 and then changing it to move the weld’s offset for the tween.

tweenService = game:GetService("TweenService")
prompt = script.Parent.Main.ProximityPrompt
door = script.Parent.Door.Weld

tweenInfo = TweenInfo.new(
		8,
		Enum.EasingStyle.Sine,
		Enum.EasingDirection.InOut			
		)

tweenOpen = tweenService:Create(door, tweenInfo, {C0 = CFrame.new(0,0,0)})

tweenClose = tweenService:Create(door, tweenInfo, {C0 = CFrame.new(1.39,0,0)})


prompt.Triggered:Connect(function()

	if prompt.ActionText == "Close" then
		prompt.Enabled = false
		task.wait(.4)
		tweenClose:Play()
		tweenClose.Completed:Wait()
		
		prompt.ActionText = "Open"
		prompt.Enabled = true
	else
		prompt.Enabled = false
		task.wait(1)
		tweenOpen:Play()
		tweenOpen.Completed:Wait()
		
		prompt.ActionText = "Close"
		prompt.Enabled = true
	end
	
end)
2 Likes

Thanks for the reply! This way, I was able to get boths tweens working. However, I’m not really able to get the values right so that it goes up and down. It either goes down and even more down, or it goes down and then just stays there, or it goes above the car on the other side… :smiley: Not really sure as I’m not so experienced with angles and stuff…

I changed the script a lot, but here is the current version.

	if plowUpPart:GetAttribute("plowPosition") == "Up" then
		goal = {C1 = CFrame.new(1.687, 3.501, -9.573) * CFrame.Angles(math.rad(-19.005), math.rad(179.967), math.rad(0.046))}
		plowUpPart:SetAttribute("plowPosition", "Down")
	else
		goal = {C1 = CFrame.new(1.687, 0.73, -10.756) * CFrame.Angles(0, math.rad(180), 0)}
		plowUpPart:SetAttribute("plowPosition", "Up")
	end