I’m currently creating a swordfighting related game, and I’ve scripted (not a scripter, so I tried my best) a shop UI that lets players buy items, shows a confirmationUI, and then deducts the gems and allows them to equip the sword.
However, I’d like to adjust the script so players can only equip one sword from the shop at once. I have no idea on where to start and would appreciate some guidance, thanks.
PurchaseScript
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local buyButton = script.Parent
local equipButton = script.Parent.EquipButton
local clickSound = game.ReplicatedStorage.GameSounds.ClickSound
local hoverSound = game.ReplicatedStorage.GameSounds.HoverSound
local sword_to_give = script.Parent.Name
local sword = ReplicatedStorage.Swords:FindFirstChild(sword_to_give)
local gemCost = script.Parent.Price.Value
local buyButtonConnection
local yesButtonConnection
local uiElement = game.Players.LocalPlayer.PlayerGui:WaitForChild("UserUI").SwordPurchaseUI
local function TweenUI()
uiElement.Position = UDim2.new(0.5, 0, 1.5, 0)
uiElement.Size = UDim2.new(0, 0, 0, 0)
uiElement.Visible = true
game.Lighting.Blur.Enabled = true
local tweenInfo = TweenInfo.new(
1,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out,
0,
false,
0
)
local targetProperties = {
Position = UDim2.new(0.275, 0,0.258, 0),
Size = UDim2.new(0, 589,0, 387),
}
local tween = TweenService:Create(uiElement, tweenInfo, targetProperties)
tween:Play()
end
script.Parent.MouseEnter:Connect(function()
hoverSound:Play()
end)
local function buyItem()
local player = Players.LocalPlayer
local playerGui = player.PlayerGui
clickSound:Play()
script.Parent.Parent.Parent.Visible = false
local confirmationUI = playerGui.UserUI.SwordConfirmationUI
confirmationUI.SwordName.Text = sword_to_give
if confirmationUI then
confirmationUI.Visible = true
confirmationUI.GemsCost.Text = gemCost
confirmationUI.SwordImage_Outline.Image = script.Parent.ImageLabel.Image
confirmationUI.SwordImage.Image = confirmationUI.SwordImage_Outline.Image
game.Lighting.Blur.Enabled = true
local yesButton = confirmationUI:FindFirstChild("YesButton")
if yesButton then
yesButtonConnection = yesButton.MouseButton1Click:Connect(function()
if player.leaderstats.Gems.Value >= gemCost then
confirmationUI.Visible = false
equipButton.Visible = true
player.leaderstats.Gems.Value = player.leaderstats.Gems.Value - gemCost
buyButtonConnection:Disconnect()
yesButtonConnection:Disconnect()
game.Players.LocalPlayer.PlayerGui.Frames.SwordsFrame.Visible = false
game.ReplicatedStorage.GameSounds.ClickSound:Play()
uiElement.GemCost.Text = gemCost
uiElement.SwordName.Text = sword_to_give
uiElement.SwordImage.Image = script.Parent.ImageLabel.Image
TweenUI()
game.ReplicatedStorage.GameSounds.PurchaseSound:Play()
else
confirmationUI.YesButton.Image = "rbxassetid://17330634285"
wait(2)
confirmationUI.YesButton.Image = "rbxassetid://17324203359"
end
end)
end
local noButton = confirmationUI:FindFirstChild("NoButton")
if noButton then
noButton.MouseButton1Click:Connect(function()
if yesButtonConnection then
yesButtonConnection:Disconnect()
end
confirmationUI.Visible = false
game.ReplicatedStorage.GameSounds.ClickSound:Play()
script.Parent.Parent.Parent.Visible = true
game.Lighting.Blur.Enabled = false
end)
end
end
end
buyButtonConnection = buyButton.MouseButton1Click:Connect(buyItem)
equipButton.MouseEnter:Connect(function()
game.ReplicatedStorage.GameSounds.HoverSound:Play()
end)
equipButton.MouseButton1Click:Connect(function()
game.ReplicatedStorage.GameSounds.ClickSound:Play()
if equipButton.Image == "rbxassetid://17316025753" then
if sword then
local swordClone = sword:Clone()
swordClone.Parent = Players.LocalPlayer.Backpack
equipButton.Image = "rbxassetid://17316048949"
end
elseif equipButton.Image == "rbxassetid://17316048949" then
local equippedSword = Players.LocalPlayer.Backpack:FindFirstChild(sword_to_give)
if equippedSword then
equippedSword:Destroy()
equipButton.Image = "rbxassetid://17316025753"
end
end
end)
You can add the sword to a starter pack name “sword”. From there, you can check if the starter pack has a tool name sword. If it does, it means the player have already equipped a sword. From there, you can replace that sword with the new sword from the shop.
I highly recommend utilizing Roblox’s DataStore service. Data stores allow you to store and retrieve data across server shutdowns and player sessions, ensuring that players’ progress is saved.
By using a data store, you can store information about which players have equipped swords and retrieve this information whenever needed. This way, even if a player leaves and rejoins the game, their equipped sword status will be retained.
I was also worrying about this, as you can see the PurchaseScript is really messy and basic since I have little programming experience but enough to understand things.
Do you think you could provide a sample/short explanation on how I would use DataStore within this script? Thanks alot.
LocalScripts cannot directly access data stores. However, you can work around this limitation by using RemoteEvents or RemoteFunctions. These allow the LocalScript to send requests or data to the server, which can then handle the data store interactions.
I would also highly recommend learning about DataStore from the Roblox documentation, as it provides a great overview of how it works. I’m here to help you, not to spoon-feed you code… You can find more information in the Data Stores Documentation on the Roblox Creator Hub.
I don’t want to be spoon-fed, I’m just asking if I could get some pointers or samples so I can work from there.
I’m not a scripter/programmer so these new terms are difficult for me, I appreciate the documentation you’ve provided me however I’m really going to need some further explanation on how I would work around the DataStore limitation by using a RemoteEvent or RemoteFunction.
Again, I don’t wish to be spoon-fed as I am also interested in learning for myself I’d just appreciate some advice on how I would use one of the two RemoteEvent or RemoteFunction to work around the DataStore limitation within LocalScripts as I’ve just looked through the documentation but still struggling to understand, thanks.
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local buyButton = script.Parent
local equipButton = script.Parent.EquipButton
local clickSound = ReplicatedStorage.GameSounds.ClickSound
local hoverSound = ReplicatedStorage.GameSounds.HoverSound
local sword_to_give = script.Parent.Name
local sword = ReplicatedStorage.Swords:FindFirstChild(sword_to_give)
local gemCost = script.Parent.Price.Value
local buyButtonConnection
local yesButtonConnection
local uiElement = game.Players.LocalPlayer.PlayerGui:WaitForChild("UserUI").SwordPurchaseUI
-- Added: Variable to track the currently equipped sword
local currentlyEquippedSword = nil
local function TweenUI()
-- TweenUI Code Unchanged
end
-- Unchanged: MouseEnter Connections
local function buyItem()
-- buyItem Code Unchanged, except for parts that involve equipping swords
end
buyButtonConnection = buyButton.MouseButton1Click:Connect(buyItem)
equipButton.MouseEnter:Connect(function()
-- Unchanged: Play HoverSound
end)
equipButton.MouseButton1Click:Connect(function()
clickSound:Play()
local player = Players.LocalPlayer
local backpack = player.Backpack
if equipButton.Image == "rbxassetid://17316025753" then
if sword then
-- Check if another sword is already equipped
if currentlyEquippedSword then
-- If so, remove the previously equipped sword
local prevEquippedSword = backpack:FindFirstChild(currentlyEquippedSword)
if prevEquippedSword then
prevEquippedSword:Destroy()
end
end
-- Equip the new sword and update the currently equipped sword
local swordClone = sword:Clone()
swordClone.Parent = backpack
currentlyEquippedSword = sword_to_give
equipButton.Image = "rbxassetid://17316048949"
end
elseif equipButton.Image == "rbxassetid://17316048949" then
local equippedSword = backpack:FindFirstChild(sword_to_give)
if equippedSword then
equippedSword:Destroy()
equipButton.Image = "rbxassetid://17316025753"
-- Update the currently equipped sword to nil since no sword is equipped now
currentlyEquippedSword = nil
end
end
end)
In the server script, the code retrieves data from the DataStore to determine if players have swords equipped, and it listens for RemoteFunction calls named “EquipSwordFunction” to handle requests from clients.
local DataStoreService = game:GetService("DataStoreService")
local equippedSwordsDataStore = DataStoreService:GetDataStore("EquippedSwords")
-- Example of a RemoteFunction?
game:GetService("ReplicatedStorage").EquipSwordFunction.OnServerInvoke = function(player)
-- Handle DataStore here (read/write data)
local success, equipped = pcall(function()
return equippedSwordsDataStore:GetAsync(tostring(player.UserId))
end)
if success then
return equipped or false
else
warn("Error", player.Name)
return false
end
end
In the LocalScript, the code invokes the RemoteFunction “EquipSwordFunction” on the server, passing the local player as an argument, and it handles the server’s response by printing whether the player has a sword equipped or logging an error message if the invocation fails, these should get you started.
local success, isEquipped = pcall(game:GetService("ReplicatedStorage").EquipSwordFunction.InvokeServer, game.Players.LocalPlayer)
if success then
print("Sword equipped?", isEquipped)
else
warn("Error?", isEquipped)
end
I want to give a little more information to what @Xethele is trying to say, you can try storing some value as a dictionary so that when you retrieve the saved value from Datastore, you can have the code act upon that value. For example:
-- This is pseudocode, none of this would run when copy and pasting
Datastore = DataContainer
Data = Get player data from datastore
if data then
if data.equipSwordData = 5 then
equip sword type 5 to player
end
end
function storingData()
dataTable = {
swordEquipData = current sword type equipped
}
Datastore.storedata = dataTable
end
You Need remove the already tool and after remove give
local ok = character:findfirstchild(“Your2Tool”)
if ok
ok:Destroy()
end
YourTool:Clone.Parent = character
– This make one sword per time in you character/backpack
Put the swords in the player game.players.player.backback INSTEAD of just parenting it to the player model. this allows for inserting tools without equipping more then 1.