Help with shop script that wont work

This script doesnt work when i click buy it doesnt come with any error and sometimes comes up with script timeout, keep in mind that i have 2 versions of this script as there are multiples shops does anyone know how to fix this, heres the scripts

Please wrap your code in two ``` 's. Your post is currently messy without it.

Code looks like this when wrapped in two of these: ```

Anyways, does the error state what line is problematic? Does the script timeout say which line is crashing your code?

this is the local script

local characters = game.ReplicatedStorage.folder:WaitForChild(“CharactersFolder”)
local remoteEvent = game.ReplicatedStorage.folder:WaitForChild(“CharacterShopRE”)

local ownedCharacters = game.Players.LocalPlayer:WaitForChild(“OwnedCharacters2”)

function setupGui(scrollingFrame, folder)

local canvasPosition = scrollingFrame.CanvasPosition

for i, child in pairs(scrollingFrame:GetChildren()) do
	if child:IsA("Frame") then child:Destroy() end
end
scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, 0)

local frames = {}

for i, character in pairs(folder:GetChildren()) do

	local newFrame = script.CharacterPreviewFrame:Clone()
	newFrame.CharacterNameLabel.Text = character.Name

	local camera = Instance.new("Camera", newFrame.CharacterViewportFrame)
	newFrame.CharacterViewportFrame.CurrentCamera = camera

	local characterModel = game.ReplicatedStorage.folder.CharactersFolder[character.Name]:Clone()
	characterModel.Parent = newFrame.CharacterViewportFrame
	
	local hrp = characterModel.PrimaryPart
	camera.CFrame = CFrame.new(hrp.Position + hrp.CFrame.LookVector * 7, hrp.Position)

	newFrame.ViewButton.MouseButton1Click:Connect(function()

		local viewerFrame = scrollingFrame.Parent.Parent.CharacterViewerFrame
		viewerFrame.CharacterNameLabel.Text = character.Name

		if viewerFrame:FindFirstChild("PriceLabel") then
			viewerFrame.PriceLabel.Text = "$" .. character.Price.Value
		end
		
		viewerFrame.CharacterViewportFrame:ClearAllChildren()

		local camera2 = camera:Clone()
		camera2.Parent = viewerFrame.CharacterViewportFrame
		viewerFrame.CharacterViewportFrame.CurrentCamera = camera2

		local characterModel2 = characterModel:Clone()
		characterModel2.Parent = viewerFrame.CharacterViewportFrame

		local button = viewerFrame:FindFirstChild("BuyButton") or viewerFrame:FindFirstChild("EquipButton")

		if button.Name == "BuyButton" and ownedCharacters:FindFirstChild(character.Name) then
			button.Text = "OWNED"
			button.BackgroundColor3 = Color3.fromRGB(195, 195, 195)

		elseif button.Name == "EquipButton" and game.Players.LocalPlayer.EquippedCharacter2.Value == character.Name then
			button.Text = "USING"
			button.BackgroundColor3 = Color3.fromRGB(195, 195, 195)

		else
			button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
			
			if button.Name == "BuyButton" then button.Text = "BUY"
			elseif button.Name == "EquipButton" then button.Text = "USE"
			end
		end

		viewerFrame.Visible = true
	end)
	
	table.insert(frames, newFrame)
end

table.sort(frames, function(a, b)
	local aPrice = game.ReplicatedStorage.folder.CharactersFolder[a.CharacterNameLabel.Text].Price.Value
	local bPrice = game.ReplicatedStorage.folder.CharactersFolder[b.CharacterNameLabel.Text].Price.Value
	return aPrice < bPrice
end)

local frameSize = nil

for i, frame in pairs(frames) do
	frame.Parent = scrollingFrame
	frame.Size = frameSize or UDim2.new(0, frame.AbsoluteSize.X, 0, frame.AbsoluteSize.Y)
	if i == 1 then frameSize = frame.Size end
	scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, scrollingFrame.UIListLayout.AbsoluteContentSize.Y)
end

if scrollingFrame.Parent.Parent.CharacterViewerFrame.Visible == true then
	if scrollingFrame.Parent.Parent.Name == "ShopFrame" and ownedCharacters:FindFirstChild(scrollingFrame.Parent.Parent.CharacterViewerFrame.CharacterNameLabel.Text) then
		scrollingFrame.Parent.Parent.CharacterViewerFrame.BuyButton.Text = "OWNED"
		scrollingFrame.Parent.Parent.CharacterViewerFrame.BuyButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
	elseif scrollingFrame.Parent.Parent.Name == "InventoryFrame" and game.Players.LocalPlayer.EquippedCharacter2.Value == scrollingFrame.Parent.Parent.CharacterViewerFrame.CharacterNameLabel.Text then
		scrollingFrame.Parent.Parent.CharacterViewerFrame.EquipButton.Text = "USING"
		scrollingFrame.Parent.Parent.CharacterViewerFrame.EquipButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
	elseif scrollingFrame.Parent.Parent.Name == "InventoryFrame" then
		scrollingFrame.Parent.Parent.CharacterViewerFrame.EquipButton.Text = "USE"
		scrollingFrame.Parent.Parent.CharacterViewerFrame.EquipButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	end
end
scrollingFrame.CanvasPosition = canvasPosition

end

setupGui(script.Parent.ShopFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, characters)
setupGui(script.Parent.InventoryFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, ownedCharacters)

characters.ChildAdded:Connect(function()
setupGui(script.Parent.ShopFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, characters)
end)
ownedCharacters.ChildAdded:Connect(function()
setupGui(script.Parent.InventoryFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, ownedCharacters)
setupGui(script.Parent.ShopFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, characters)
end)

script.Parent.ShopFrame.CharacterViewerFrame.BuyButton.MouseButton1Click:Connect(function()
local charName = script.Parent.ShopFrame.CharacterViewerFrame.CharacterNameLabel.Text
remoteEvent:FireServer(charName, “buy”)

end)

script.Parent.InventoryFrame.CharacterViewerFrame.EquipButton.MouseButton1Click:Connect(function()
local charName = script.Parent.InventoryFrame.CharacterViewerFrame.CharacterNameLabel.Text
remoteEvent:FireServer(charName, “use”)
wait(0.1)
setupGui(script.Parent.InventoryFrame.CharacterScrollingBackgroundFrame.CharacterScrollingFrame, ownedCharacters)
end)

script.Parent.ShopFrame.Visible = false
script.Parent.ShopFrame.CharacterViewerFrame.Visible = false
script.Parent.InventoryFrame.Visible = false
script.Parent.InventoryFrame.CharacterViewerFrame.Visible = false

script.Parent.ShopButton.MouseButton1Click:Connect(function()
script.Parent.ShopFrame.Visible = not script.Parent.ShopFrame.Visible
script.Parent.InventoryFrame.Visible = false
end)
script.Parent.InventoryButton.MouseButton1Click:Connect(function()
script.Parent.InventoryFrame.Visible = not script.Parent.InventoryFrame.Visible
script.Parent.ShopFrame.Visible = false
end)
script.Parent.ShopFrame.CloseButton.MouseButton1Click:Connect(function()
script.Parent.ShopFrame.Visible = false
end)
script.Parent.InventoryFrame.CloseButton.MouseButton1Click:Connect(function()
script.Parent.InventoryFrame.Visible = false
end)

its at line 16

As for the script timeout it doesnt say but the for the local script it is at line 36

" local dss = game:GetService(“DataStoreService”)
local ds = dss:GetDataStore(“CharacterShopData2”)

function saveData(player)

local charactersList = {}

for i, character in pairs(player.OwnedCharacters2:GetChildren()) do
	table.insert(charactersList, character.Name)
end

ds:SetAsync(player.UserId .. "Characters", charactersList)
ds:SetAsync(player.UserId .. "LastCharacter", player.EquippedCharacter2.Value)

game.ReplicatedStorage.folder.OriginalCharacters[player.Name]:Destroy()

end

function changeCharacter(player, character)

local oldCharacter = player.Character2
local newCharacter = character:Clone()

newCharacter.HumanoidRootPart.CFrame = player.Character2.HumanoidRootPart.CFrame
newCharacter.HumanoidRootPart.Anchored = false
newCharacter.Name = player.Character2.Name
player.Character2 = newCharacter

for i, child in pairs(game.ReplicatedStorage.folder.OriginalCharacters[player.Name]:GetChildren()) do
	if child:IsA("LocalScript") or child:IsA("Script") then
		child:Clone().Parent = newCharacter
	end
end

newCharacter.Parent = workspace
oldCharacter:Destroy()

end

game.Players.PlayerAdded:Connect(function(player)

local charFolder = Instance.new("Folder")
charFolder.Name = "OwnedCharacters2"
charFolder.Parent = player

local equippedChar = Instance.new("StringValue")
equippedChar.Name = "EquippedCharacter2"
equippedChar.Parent = player

local lastCharSaved = ds:GetAsync(player.UserId .. "LastCharacter")
equippedChar.Value = lastCharSaved or ""

local ls = player.leaderstats

local cash = ls.Coins



local savedCharacters = ds:GetAsync(player.UserId .. "Characters") or {}

for i, character in pairs(savedCharacters) do
	if game.ReplicatedStorage.folder:WaitForChild("CharactersFolder"):FindFirstChild(character) then
		game.ReplicatedStorage.folder.CharactersFolder[character]:Clone().Parent = charFolder
	end
end

if not player.Character then player.CharacterAdded:Wait() end
player.Character.Archivable = true
local originalCharacter = player.Character:Clone()
originalCharacter.Parent = game.ReplicatedStorage.folder.OriginalCharacters

if lastCharSaved and game.ReplicatedStorage.folder.CharactersFolder:FindFirstChild(lastCharSaved) then
	changeCharacter(player, game.ReplicatedStorage.folder.CharactersFolder[lastCharSaved])
end

local debounce = false
player.CharacterAdded:Connect(function(char)
	if game.ReplicatedStorage.folder.CharactersFolder:FindFirstChild(equippedChar.Value) and not debounce then
		debounce = true
		changeCharacter(player, game.ReplicatedStorage.folder.CharactersFolder[equippedChar.Value])
		wait(1)
		debounce = false
	end
end)

end)

game.Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function()
for i, player in pairs(game.Players:GetPlayers()) do
saveData(player)
end
end)

game.ReplicatedStorage.folder:WaitForChild(“CharacterShopRE”).OnServerEvent:Connect(function(player, character, instruction)

if game.ReplicatedStorage.CharactersFolder:FindFirstChild(character) then
	local charRequested = game.ReplicatedStorage.folder.CharactersFolder[character]

	if instruction == "buy" then

		if not player.OwnedCharacters2:FindFirstChild(character) and player.leaderstats.Coins.Value >= charRequested.Price.Value then

			player.leaderstats.Coins.Value -= charRequested.Price.Value
			charRequested:Clone().Parent = player.OwnedCharacters2
		end

	elseif instruction == "use" then

		if player.OwnedCharacters2:FindFirstChild(character) then

			if player.EquippedCharacter2.Value == character then	
				player.EquippedCharacter2.Value = ""
				changeCharacter(player, game.ReplicatedStorage.folder.OriginalCharacters[player.Name])

			else
				player.EquippedCharacter2.Value = character
				changeCharacter(player, charRequested)
			end
		end
	end
end

end) "

I’m pretty sure we’re seeing different lines of code. The first script leads to an empty line for me, while the second goes to an end. Can you simply say the exact lines of code instead?

And please, use ``` when pasting code.






Sorry is this easier?

The problem is that when i click buy the script doesnt do anything no errors are occuring anymore but before it said script timeout

A screenshot isn’t what I was expecting. Simply copy the problematic line to your reply as text.

What were you expecting when you click the Buy button? Should the script do an animation, give you the item, etc.?

The script is supposed to say owned and then it appears in the inventory, I have another version of this model for a different shop and it works perfectly fine but here i just buy and nothing happens i didnt post the problematic line because it doesnt show but before the problematic line used to be this

newCharacter.Parent = workspace

but now that error doesnt show anymore and before it also used to say script timeout but doesnt show it wasnt at any specific line

Do you have any idea how i fix this?

I found one issue, here’s a fix.

I changed this:

local button = viewerFrame:FindFirstChild("BuyButton") or viewerFrame:FindFirstChild("EquipButton")

if button.Name == "BuyButton" and ownedCharacters:FindFirstChild(character.Name) then
	button.Text = "OWNED"
	button.BackgroundColor3 = Color3.fromRGB(195, 195, 195)

elseif button.Name == "EquipButton" and game.Players.LocalPlayer.EquippedCharacter2.Value == character.Name then
	button.Text = "USING"
	button.BackgroundColor3 = Color3.fromRGB(195, 195, 195)

else
	button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)

	if button.Name == "BuyButton" then button.Text = "BUY"
	elseif button.Name == "EquipButton" then button.Text = "USE"
	end
end

to this:

local buyButton = viewerFrame:FindFirstChild("BuyButton")
local equipButton = viewerFrame:FindFirstChild("EquipButton")

if buyButton then
	if ownedCharacters:FindFirstChild(character.Name) then
		buyButton.Text = "OWNED"
		buyButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
	else
		buyButton.Text = "BUY"
		buyButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	end
end

if equipButton then
	if game.Players.LocalPlayer.EquippedCharacter2.Value == character.Name then
		equipButton.Text = "USING"
		equipButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
	else
		equipButton.Text = "USE"
		equipButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	end
end

The problem with the original code is that once the ViewButton is clicked, the script looks for a BuyButton and returns that. If it doesn’t find a BuyButton, it will look for EquipButton and then return that. If both buttons are absent, the variable button is nil.

I assume both buttons are always present. If they are, the BuyButton will only be edited, as it is the button that was first checked. The EquipButton won’t be checked unless the BuyButton wasn’t there. Now, the new code looks for both buttons.

I’m still looking for other problems unless my answer is enough.

I will test the code and get back to you if theres any problem thx

You are right in them bothm being prescent at the same time but the problem is still occuring

Btw it is the buy button that wont do anything when you click it it is supposed to say owned and then it goes to the player inventory

The code now gets me quite confused, but here is my shot:

local function updateButtons()
	if buyButton then
		if ownedCharacters:FindFirstChild(character.Name) then
			buyButton.Text = "OWNED"
			buyButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
		else
			buyButton.Text = "BUY"
			buyButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		end
	end

	if equipButton then
		if game.Players.LocalPlayer.EquippedCharacter2.Value == character.Name then
			equipButton.Text = "USING"
			equipButton.BackgroundColor3 = Color3.fromRGB(195, 195, 195)
		else
			equipButton.Text = "USE"
			equipButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		end
	end
end

updateButtons()

remoteEvent.OnClientEvent:Connect(updateButtons)

This requires the server script to confirm that the buying process is complete. You have to somehow trigger the RemoteEvent again from the server back to the player who bought the item. Something like remoteEvent:FireClient(player)

I’m a little concerned about the code you are using, as well as adding this solution to the mix. I figured this would cause a slight memory leak. I wouldn’t be able to help with cleaning up the code, as I cannot accurately reproduce the exact behavior of the code based on it alone.

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