Crafting system dosen't work

The actual problem is, whenever I start building, everything is fine, but when you switch to something else, it breaks and puts down the last thing you chose to build, here is a video.
robloxapp-20210306-1123133.wmv (7.8 MB)

I did some researching in my code and found out the problem is in a function called “Unpack”
the function sorts the buttons to work, as it detects everything inside a folder called “Craftable” located inside ReplicatedStorage. The problem is, it can’t detect whenever the object you’re using is the same or not. I can’t seem to detect the problem, here is the code:

     function unPack(list)
	for i, object in pairs(list) do
		local button = Instance.new("TextButton", p.PlayerGui.craftingGui.Frame.catalouge)
		button.Text = tostring(object.Name)
		local hasSpace = button.Text:split("_")
		if hasSpace[2] then
			button.Text = tostring(hasSpace[1]).. " ".. tostring(hasSpace[2])
			if hasSpace[3] then
				if not hasSpace[4] then
					button.Text = tostring(hasSpace[1]).. " ".. tostring(hasSpace[2]).. " ".. tostring(hasSpace[3])
				else
					button.Text = tostring(hasSpace[1]).. " ".. tostring(hasSpace[2]).. " ".. tostring(hasSpace[3]).. " ".. tostring(hasSpace[4])
				end
				
			end
		end
		
		button.Font = Enum.Font.SourceSansItalic
		button.TextScaled = true
		button.BackgroundTransparency = 1
		button.TextColor3 = Color3.fromRGB(81, 81, 81)
		button.MouseButton1Click:Connect(function()
			if object.Parent.Name == "Purchasable" then
					local ammount = p.leaderstats.Cash
					script.Parent.craftingGui.confirm.Visible = true
					script.Parent.craftingGui.confirm.title.warning.Text = "Are you sure you want to purchase ".. object.Name .." for ".. tostring(object.Cash.Value).." Cash?"
					if tonumber(ammount.Value) >= tonumber(object.Cash.Value) then
						script.Parent.craftingGui.confirm.confirmation.ye.MouseButton1Click:Connect(function()
						if tonumber(ammount.Value) > tonumber(object.Cash.Value) or tonumber(ammount.Value) == tonumber(object.Cash.Value) then
							ammount.Value = tonumber(ammount.Value) - tonumber(object.Cash.Value)
							script.Parent.craftingGui.Enabled = false
							enabled = false
							table.insert(objectsUsing, object)
							CraftingService.StartBuilding(objectsUsing[1], p.Character or p.CharacterAdded:Wait())
						else
							script.Parent.craftingGui.confirm.confirmation.ye.Text = "Not enough cash!"
							wait(1)
							script.Parent.craftingGui.confirm.Visible = false
							wait(.1)
							script.Parent.craftingGui.confirm.confirmation.ye.Text = "Yes!"
						end
					end)
						
				script.Parent.craftingGui.confirm.confirmation.TextButton.MouseButton1Click:Connect(function()
					script.Parent.craftingGui.confirm.Visible = false
					end)
				else
					
			end
	end
		end)
	end
end

At the top there are also some variables:

    local maps = {} -- The area it sorts the buttons into (Purchaseable, resources etc.)
    local crafting = {} -- This sorts the buttons inside a table.
    local objectsUsing = {} -- This is a table to sort what I'm using, though I've tried using it and it's 
    helpless

The actual problem occurs here, inside the “Unpack” function

    button.MouseButton1Click:Connect(function()
			if object.Parent.Name == "Purchasable" then
					local ammount = p.leaderstats.Cash
					script.Parent.craftingGui.confirm.Visible = true
					script.Parent.craftingGui.confirm.title.warning.Text = "Are you sure you want to purchase ".. object.Name .." for ".. tostring(object.Cash.Value).." Cash?"
					if tonumber(ammount.Value) >= tonumber(object.Cash.Value) then
						script.Parent.craftingGui.confirm.confirmation.ye.MouseButton1Click:Connect(function()
						if tonumber(ammount.Value) > tonumber(object.Cash.Value) or tonumber(ammount.Value) == tonumber(object.Cash.Value) then
							ammount.Value = tonumber(ammount.Value) - tonumber(object.Cash.Value)
							script.Parent.craftingGui.Enabled = false
							enabled = false
							table.insert(objectsUsing, object)
							CraftingService.StartBuilding(objectsUsing[1], p.Character or p.CharacterAdded:Wait())
						else
							script.Parent.craftingGui.confirm.confirmation.ye.Text = "Not enough cash!"
							wait(1)
							script.Parent.craftingGui.confirm.Visible = false
							wait(.1)
							script.Parent.craftingGui.confirm.confirmation.ye.Text = "Yes!"
						end
					end)
						
				script.Parent.craftingGui.confirm.confirmation.TextButton.MouseButton1Click:Connect(function()
					script.Parent.craftingGui.confirm.Visible = false
					end)
				else
					
			end
	end
		end)
1 Like

I’ve only recently started scripting, but I believe the issue here is that you insert the object into the objectsUsing table but I don’t think you ever remove it from the table so everytime it checks the table it will always get the first object you put in there.

I will test this out, thanks for the info.

1 Like

So i’ve tried this and,

button.MouseButton1Click:Connect(function()
		if object.Parent.Name == "Purchasable" then
				local ammount = p.leaderstats.Cash
				script.Parent.craftingGui.confirm.Visible = true
				script.Parent.craftingGui.confirm.title.warning.Text = "Are you sure you want to purchase ".. object.Name .." for ".. tostring(object.Cash.Value).." Cash?"
				if tonumber(ammount.Value) >= tonumber(object.Cash.Value) then
					script.Parent.craftingGui.confirm.confirmation.ye.MouseButton1Click:Connect(function()
					if tonumber(ammount.Value) > tonumber(object.Cash.Value) or tonumber(ammount.Value) == tonumber(object.Cash.Value) then
						ammount.Value = tonumber(ammount.Value) - tonumber(object.Cash.Value)
						script.Parent.craftingGui.Enabled = false
						enabled = false
						if objectsUsing[1] then
							table.remove(objectsUsing, 1)
						end
						table.insert(objectsUsing, object)
						CraftingService.StartBuilding(objectsUsing[1], p.Character or p.CharacterAdded:Wait())
					else
						script.Parent.craftingGui.confirm.confirmation.ye.Text = "Not enough cash!"
						wait(1)
						script.Parent.craftingGui.confirm.Visible = false
						wait(.1)
						script.Parent.craftingGui.confirm.confirmation.ye.Text = "Yes!"
					end
				end)
					
			script.Parent.craftingGui.confirm.confirmation.TextButton.MouseButton1Click:Connect(function()
				script.Parent.craftingGui.confirm.Visible = false
				end)
			else
				
		end
end
	end)

This happens:


Even though inside the code, it does this with my module script:

1. CraftingService = require(game.ReplicatedStorage.CraftingService)
   
100. CraftingService.StartBuilding(objectsUsing[1], p.Character or p.CharacterAdded:Wait())

On line 100 (As shown) calls the first thing inside objectsUsing (objectsUsing[1])
but it gets changed before it happens shown here:

objectsUsing = {}
if objectsUsing[1] then
    table.remove(objectsUsing, 1)
else
	print("Clean!")
end

It this not what you want? What is the exact issue here? Sorry, I just don’t understand.

Ah, in the picture it dosen’t show this, but the wood planks are below the wood wall, which is the problem here.

Where is the objectsUsing Table? As in what line is the same as layout as the last code you sent?

the table is located in Line 10.

You should try printing what ever is inside of table[1] and see if it does actually remove it. Try printing before checking the table, and after adding the new object inside of it. Try print table[1] and table[2] just in case.

I’ve got… weird results. It prints “nil/nil” as I made it print the first thing and the second thing after a slash, and thats normal, but then it prints: “Wood_planks/nil” then it prints, “Wood_wall/nil”, even though I only made it print ONCE?

Can I see the code where you printed it?

Are you sure it’s not an issue with StartBuilding? Right now the only issue I see is you never disabled the gui that confirms you want to buy something after buying it, which is why the gui stays open after buying something, at the end of the if statement I’d add something to disable that too

if tonumber(ammount.Value) >= tonumber(object.Cash.Value) then
	ammount.Value = tonumber(ammount.Value) - tonumber(object.Cash.Value)
	script.Parent.craftingGui.Enabled = false
	enabled = false
	table.insert(objectsUsing, object)
	CraftingService.StartBuilding(objectsUsing[1], p.Character or p.CharacterAdded:Wait())
	script.Parent.craftingGui.confirm.Visible = false

Because disabling the main gui doesn’t disable the ones under it when you reenable it, hence why it appears again.

(I also changed the if statement because the other condition is just the = part of >=

But in terms of your other issue, I’m not sure what it could be. Also,

Where’s this bit of code located if I may ask?

local objectsUsing = {} --// Just so then I can show the code lol
print(tostring(objectsUsing[1]).. "/" ..tostring(objectsUsing[2])) --// What it is.
--// It's placed before doing the "if objectsUsing[1] then".

So this prints the itemName and then nil, twice?

If you’re asking where the StartBuilding() function is placed, then it’s inside a ModuleScript,
this is the code for it:

local CS = {}
CS.Building = false
function CS.EndBuilding(visualPart, Playercharacter, list)
    if CS.Building == true then
    	CS.Building = false
    	local p = game.Players.LocalPlayer
	    local m = p:GetMouse()
    	local tweenInfo = TweenInfo.new(1)
    	local camera = workspace.CurrentCamera
    	Playercharacter:WaitForChild("Humanoid").WalkSpeed = 16
    	Playercharacter:WaitForChild("Humanoid").JumpPower = 50
    	local placedPart = visualPart:Clone()
    	placedPart.Parent = workspace
    	placedPart.Anchored = true
	    placedPart.UsePartColor = false
    	placedPart.Transparency = 0
    	placedPart.Position = visualPart.Position
		wait(.1)
		visualPart:Destroy()
    	repeat wait()
    		camera.CameraType = Enum.CameraType.Custom
     	until camera.CameraType == Enum.CameraType.Custom
	else
    	warn("Not building!")
   end
end

Yes, that is correct, it indeed does.

I think you sent the code for the wrong function since this is for EndBuilding, not StartBuilding

Oh whoops, sorry about that, this is the correct code:

    function CS.StartBuilding(item, character, list)
	        CS.Building = true
			local p = game.Players.LocalPlayer
			local m = p:GetMouse()
			local tweenInfo = TweenInfo.new(1)
			local camera = workspace.CurrentCamera
			local visual = item:Clone()
			visual.Anchored = true
			local placed = Instance.new("BoolValue", visual)
			placed.Value = false
			visual.Parent = workspace
			visual.BrickColor = BrickColor.new("Lime green")
			visual.UsePartColor = true
			visual.Position = Vector3.new(character.HumanoidRootPart.Position.X, item.Position.Y, character.HumanoidRootPart.Position.Z + 15)
			repeat wait()
				camera.CameraType = Enum.CameraType.Scriptable
			until camera.CameraType == Enum.CameraType.Scriptable
			character:WaitForChild("Humanoid").WalkSpeed = 0
			character:WaitForChild("Humanoid").JumpPower = 0
			uis.InputBegan:Connect(function(key)
				if key.KeyCode == Enum.KeyCode.W and placed.Value == false then
					visual.Position = Vector3.new(visual.Position.X, visual.Position.Y + 1, visual.Position.Z)
				end
				
				if key.KeyCode == Enum.KeyCode.S and placed.Value == false then
					visual.Position = Vector3.new(visual.Position.X, visual.Position.Y - 1, visual.Position.Z)
				   end
				
				if key.KeyCode == Enum.KeyCode.F then
					
					CS.StopBuilding(visual, character , list)
				    end
				
				if key.KeyCode == Enum.KeyCode.E then
					CS.EndBuilding(visual, character, list)
				end
			end)
			repeat wait()
				visual.CFrame = CFrame.new(m.Hit.X, visual.CFrame.Y, m.Hit.Z)
			until placed.Value == true
			return visual and character
    end

Shouldn’t it be return visual,character or am I mistaken?

Oh that’s correct… let me try that lol