How to make two objects weld to each other when they touch and make it a toggleable option

Hey there!

I am trying to get parts to weld to each other when I activate a ProximityPrompt, but I can’t seem to get it working. Here are my scripts:

this script is inside WeldedPart:

local weldDebounce = false

script.Parent.Touched:Connect(function(hit)
	if hit.Parent.Name == "WeldedPart" and hit.Parent.Transparency ~= 1 and hit.Name == "Droplet" and weldDebounce == false then
		weldDebounce = true
		local weld = Instance.new("WeldConstraint")
		weld.Parent = script.Parent
		weld.Part0 = hit
		weld.Part1 = script.Parent
		weldDebounce = false
		--script:Destroy()
		--uncomment the line above if it's a one-time script
	end
end)

This script is inside my ProximityPrompt:

local button = script.Parent
local weld = script.Parent.Parent.Parent:FindFirstChild("WeldedPart")

button.Triggered:Connect(function(player)
	if weld then
		if weld.Transparency == 1 then
			weld.Transparency = 0.5
			button.ObjectText = "Unweld"
		else
			weld.Transparency = 1
			button.ObjectText = "Weld"
		end
	end
end)

For context, I’m just trying to make a game where you transport little objects as cargo in a boat across the ocean - the little objects are not anchored and they keep glitching through the boat whenever I move it, so my solution so far has been to just try and weld them to a part when the “weld” is active and they are touching said “weld” part.

Any help or advice on how to do this a better way would also be appreciated on top of just trying to get the weld to work!

I suggest no using the Touched event at all.
If you already have a ProximityPrompt, work with that.

What about, the boat has a specific number of slots.
When player is holding something and activates the ProximityPromp, the server script will take what player is holding and create the WeldConstraint to fuse the item to an available “Slot” in boat (using the slot CFrame too to place it).

So, Im holding a box, going to my boat, activate the prompt and my box gets welded to the boat.
And for grabbing my box again, same process or click detectors.

1 Like

This was an awesome idea, so I set it all up into my proximityprompt instead and made the transport a single barrel - but I’ve run into a small hurdle… Am I just not understanding if statements correctly? I want you to be able to take the barrel from the boat if you don’t have a barrel in your workspace character or in your backpack:

local button = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local weldedpart = script.Parent.Parent
welded = false

button.Triggered:Connect(function(player)
	local character = player.Character
	if character:FindFirstChild("Barrel") and welded == false then
		print("barrel yes")
		local weld = Instance.new("WeldConstraint")
		character.Barrel:FindFirstChild("Handle"):Clone().Parent = weldedpart
		weldedpart.Handle.CFrame = CFrame.new(weldedpart.Position) + Vector3.new(0, 2, 0)
		weldedpart.Handle.Orientation = Vector3.new(0, 0, -90)
		character:FindFirstChildOfClass("Tool"):Destroy()
		weld.Parent = weldedpart.Handle
		weld.Part0 = weldedpart
		weld.Part1 = weldedpart.Handle
		welded = true
		button.ObjectText = "Place"
	elseif welded == true and not character.Barrel or not Players:GetPlayerFromCharacter(player).Backpack:FindFirstChild("Barrel") then
		button.ObjectText = "Take"
		weldedpart.Handle:Destroy()
		ReplicatedStorage.Barrel:Clone().Parent = character
	end
	
end)

But I am receiving this error: Barrel is not a valid member of Model "Workspace.StrayanCini" - Server - Script:21

I understand the error, but to my understanding the barrel not existing should make the if statement run, right?

When you do this:

if character:FindFirstChild("Barrel") and welded == false then

If the barrel exist and welded is false, jump to the next if statement line, which is this one:

elseif welded == true and not character.Barrel

first check is welded which is not false, probably true, yeah, but the next check is:
character.Barrel you are telling the script that takes the barrel from the character, but theres no barrel.

Just change it to:
character:FindFirstChild("Barrel") instead of character.Barrel

1 Like

Hi, I actually just did some more testing and it’s firing the second if statement even if the barrel exists either on the character or in the player’s backpack.

elseif welded == true and not character:FindFirstChild("Barrel") or not Players:GetPlayerFromCharacter(character).Backpack:FindFirstChild("Barrel") then
		button.ObjectText = "Place"
		weldedpart.Handle:Destroy()
		ReplicatedStorage.Barrel:Clone().Parent = character
		welded = false
	end

What exactly am I doing wrong here?

Well, depends on what exactly you are looking for with the second if statement.

This:

if welded == true and not character:FindFirstChild("Barrel") or not Players:GetPlayerFromCharacter(character).Backpack:FindFirstChild("Barrel")

Means:
If welded is true AND Barrel doesnt exist, run the code.
OR if Barrel doesnt exist in Backpack, run the code

I mean, it runs if welded is true and barrel doesnt exist. OR if theres not barrel in backpack, in both cases code inside the if statement will run

Additionally, I suggest, not using that welded variable, preferably read if a weld instance exist in the object the script is manipulating.
Otherwise, you will need to create more variables per item? or needing to put many scripts like this inside each item? or restart the variable, with the risk it gets stucked in false or true forever if player is not exactly doing the steps you calculated they would do

1 Like

Wow… This makes so much more sense now. In my head it was always “if barrel or backpack barrel don’t exist, run the code”. I have changed the logic and now it works perfectly. Thank you so much!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.