Help needed on script

Hello, so I have two scripts in my game that allow players to buy trails and equip them. The problem is that each time they die they have to re-equip the trail. How do I fix this or what should I add to my script to fix this.
Here are the scripts:

The first script:

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

local trails = game.ReplicatedStorage:WaitForChild(“Trails”)

function createAtchs(char)

local hrp = char:WaitForChild("HumanoidRootPart")

local atchTop = Instance.new("Attachment", hrp)
atchTop.Name = "TrailTop"
atchTop.Position = Vector3.new(0, 0.766, 0)

local atchBtm = Instance.new("Attachment", hrp)
atchBtm.Name = "TrailBottom"
atchBtm.Position = Vector3.new(0, -0.766, 0)

end

function saveData(plrLeaving)

local ownedTrails = {}
for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
	table.insert(ownedTrails, trail.Name)
end

local success, err = pcall(function()
	ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
	ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
end)

end

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

local trailsOwned = {}

pcall(function()
	trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}

end)


local ownedFolder = Instance.new("Folder", plr)
ownedFolder.Name = "OwnedTrails"


for i, owned in pairs(trailsOwned) do
	
	if trails:FindFirstChild(owned) then
		
		trails[owned]:Clone().Parent = ownedFolder
	end
end

if plr.Character then createAtchs(plr.Character) end

plr.CharacterAdded:Connect(createAtchs)

end)

game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()

for i, plrLeaving in pairs(game.Players:GetPlayers()) do
	saveData(plrLeaving)
end

end)

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)

if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
	
	local price = trail.Price.Value
	local coins = plr.leaderstats.Coins
	
	if price <= coins.Value then
		
		coins.Value -= price
		
		
		trail:Clone().Parent = plr.OwnedTrails
	end
	
	
elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
	
	local char = plr.Character
	
	if not char or not char:FindFirstChild("HumanoidRootPart") then return end
	
	for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
		
		
		if child:IsA("Trail") then child:Destroy() end
	end
	
	
	local newTrail = trail:Clone()

	newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
	newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom

	newTrail.Parent = char.HumanoidRootPart
end

end)

The second script:

local shopFrame = script.Parent:WaitForChild(“ShopFrame”)
local invFrame = script.Parent:WaitForChild(“InventoryFrame”)

local trailsFolder = game.ReplicatedStorage:WaitForChild(“Trails”)
local ownedTrailsFolder = game.Players.LocalPlayer:WaitForChild(“OwnedTrails”)

function updateInventory()

for i, child in pairs(invFrame.TrailsScroller:GetChildren()) do

	if child:IsA("ImageLabel") then child:Destroy() end
end


local ownedTrails = ownedTrailsFolder:GetChildren()

table.sort(ownedTrails, function(a, b)
	return trailsFolder[a.Name].Price.Value < trailsFolder[b.Name].Price.Value or trailsFolder[a.Name].Price.Value == trailsFolder[b.Name].Price.Value and a.Name < b.Name
end)


for i, trail in pairs(ownedTrails) do

	local item = script.Item:Clone()
	item.SelectButton.Text = "EQUIP"
	item.TrailName.Text = trail.Name
	item.Trail.UIGradient.Color = trail.Color

	item.Parent = invFrame.TrailsScroller


	if game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart"):FindFirstChild(trail.Name) then
		item.SelectButton.Text = "EQUIPPED"
	end


	item.SelectButton.MouseButton1Click:Connect(function()
		game.ReplicatedStorage.TrailSelectedRE:FireServer(false, trail)

		for i, itemButton in pairs(item.Parent:GetChildren()) do

			if itemButton:IsA("ImageLabel") then
				itemButton.SelectButton.Text = "EQUIP"
			end
		end
		item.SelectButton.Text = "EQUIPPED"
	end)
end

end

function updateShop()

for i, child in pairs(shopFrame.Frame1Effects.TrailsScroller:GetChildren()) do

	if child:IsA("ImageLabel") then child:Destroy() end
end


local shopTrails = trailsFolder:GetChildren()

table.sort(shopTrails, function(a, b)
	return a.Price.Value < b.Price.Value or a.Price.Value == b.Price.Value and a.Name < b.Name
end)


for i, trail in pairs(shopTrails) do

	local item = script.Item:Clone()

	item.SelectButton.Text = "BUY for " .. trail.Price.Value
	if ownedTrailsFolder:FindFirstChild(trail.Name) then item.SelectButton.Text = "Owned." end

	item.TrailName.Text = trail.Name
	item.Trail.UIGradient.Color = trail.Color

	item.Parent = shopFrame.Frame1Effects.TrailsScroller


	item.SelectButton.MouseButton1Click:Connect(function()
		game.ReplicatedStorage.TrailSelectedRE:FireServer(true, trail)
	end)
end

end

updateShop()
updateInventory()

ownedTrailsFolder.ChildAdded:Connect(function()
updateInventory(); updateShop()
end)
ownedTrailsFolder.ChildRemoved:Connect(function()
updateInventory(); updateShop()
end)

trailsFolder.ChildAdded:Connect(updateShop)
trailsFolder.ChildRemoved:Connect(updateShop)

1 Like

You could make a bool value attribute and set it to true or false when they have a trail equipped or not.
If they die and the bool is true then reequip the current trail.

1 Like

In which function should I put the bool value?

1 Like
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local trails = game.ReplicatedStorage:WaitForChild("Trails")

function createAtchs(char)
	local hrp = char:WaitForChild("HumanoidRootPart")
	local atchTop = Instance.new("Attachment", hrp)
	atchTop.Name = "TrailTop"
	atchTop.Position = Vector3.new(0, 0.766, 0)
	local atchBtm = Instance.new("Attachment", hrp)
	atchBtm.Name = "TrailBottom"
	atchBtm.Position = Vector3.new(0, -0.766, 0)
end

function saveData(plrLeaving)
	local ownedTrails = {}
	for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
		table.insert(ownedTrails, trail.Name)
	end
	local success, err = pcall(function()
		ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
		ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local trailsOwned = {}
	pcall(function()
		trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}
	end)
	local ownedFolder = Instance.new("Folder", plr)
	ownedFolder.Name = "OwnedTrails"
	for i, owned in pairs(trailsOwned) do
		if trails:FindFirstChild(owned) then
			trails[owned]:Clone().Parent = ownedFolder
		end
	end
	if plr.Character then createAtchs(plr.Character) end
	plr.CharacterAdded:Connect(createAtchs)
end)

game.Players.PlayerRemoving:Connect(saveData)

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

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr.OwnedTrails
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		local char = plr.Character
		if not char or not char:FindFirstChild("HumanoidRootPart") then return end
		for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
		newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
		newTrail.Parent = char.HumanoidRootPart
	end
end)
local shopFrame = script.Parent:WaitForChild("ShopFrame")
local invFrame = script.Parent:WaitForChild("InventoryFrame")
local trailsFolder = game.ReplicatedStorage:WaitForChild("Trails")
local ownedTrailsFolder = game.Players.LocalPlayer:WaitForChild("OwnedTrails")

function updateInventory()
	for i, child in pairs(invFrame.TrailsScroller:GetChildren()) do
		if child:IsA("ImageLabel") then child:Destroy() end
	end
	local ownedTrails = ownedTrailsFolder:GetChildren()
	table.sort(ownedTrails, function(a, b)
		return trailsFolder[a.Name].Price.Value < trailsFolder[b.Name].Price.Value or trailsFolder[a.Name].Price.Value == trailsFolder[b.Name].Price.Value and a.Name < b.Name
	end)
	for i, trail in pairs(ownedTrails) do
		local item = script.Item:Clone()
		item.SelectButton.Text = "EQUIP"
		item.TrailName.Text = trail.Name
		item.Trail.UIGradient.Color = trail.Color
		item.Parent = invFrame.TrailsScroller
		if game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart"):FindFirstChild(trail.Name) then
			item.SelectButton.Text = "EQUIPPED"
		end
		item.SelectButton.MouseButton1Click:Connect(function()
			game.ReplicatedStorage.TrailSelectedRE:FireServer(false, trail)
			for i, itemButton in pairs(item.Parent:GetChildren()) do
				if itemButton:IsA("ImageLabel") then
					itemButton.SelectButton.Text = "EQUIP"
				end
			end
			item.SelectButton.Text = "EQUIPPED"
		end)
	end
end

function updateShop()
	for i, child in pairs(shopFrame.Frame1Effects.TrailsScroller:GetChildren()) do

		if child:IsA("ImageLabel") then child:Destroy() end
	end
	local shopTrails = trailsFolder:GetChildren()
	table.sort(shopTrails, function(a, b)
		return a.Price.Value < b.Price.Value or a.Price.Value == b.Price.Value and a.Name < b.Name
	end)
	for i, trail in pairs(shopTrails) do
		local item = script.Item:Clone()
		item.SelectButton.Text = "BUY for " .. trail.Price.Value
		if ownedTrailsFolder:FindFirstChild(trail.Name) then item.SelectButton.Text = "Owned." end
		item.TrailName.Text = trail.Name
		item.Trail.UIGradient.Color = trail.Color
		item.Parent = shopFrame.Frame1Effects.TrailsScroller
		item.SelectButton.MouseButton1Click:Connect(function()
			game.ReplicatedStorage.TrailSelectedRE:FireServer(true, trail)
		end)
	end
end

updateShop()
updateInventory()

ownedTrailsFolder.ChildAdded:Connect(function()
	updateInventory(); updateShop()
end)
ownedTrailsFolder.ChildRemoved:Connect(function()
	updateInventory(); updateShop()
end)

trailsFolder.ChildAdded:Connect(updateShop)
trailsFolder.ChildRemoved:Connect(updateShop)
1 Like
local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("DATA")
local trails = game.ReplicatedStorage:WaitForChild("Trails")

function saveData(plrLeaving)
	local ownedTrails = {}
	for i, trail in pairs(plrLeaving.OwnedTrails:GetChildren()) do
		table.insert(ownedTrails, trail.Name)
	end
	local success, err = pcall(function()
		ds:SetAsync("trails-" .. plrLeaving.UserId, ownedTrails)
		ds:SetAsync("Coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
	end)
end

game.Players.PlayerAdded:Connect(function(plr)
	local trailsOwned = {}
	pcall(function()
		trailsOwned = ds:GetAsync("trails-" .. plr.UserId) or {}
	end)
	local ownedFolder = Instance.new("Folder", plr)
	ownedFolder.Name = "OwnedTrails"
	for i, owned in pairs(trailsOwned) do
		if trails:FindFirstChild(owned) then
			trails[owned]:Clone().Parent = ownedFolder
		end
	end
	plr.CharacterAdded:Connect(function(char)
		local hrp = char:WaitForChild("HumanoidRootPart")
		local atchTop = Instance.new("Attachment", hrp)
		atchTop.Name = "TrailTop"
		atchTop.Position = Vector3.new(0, 0.766, 0)
		local atchBtm = Instance.new("Attachment", hrp)
		atchBtm.Name = "TrailBottom"
		atchBtm.Position = Vector3.new(0, -0.766, 0)
		if plr:FindFirstChild("LastTrail") then
			local newTrail = plr:FindFirstChild("LastTrail").Value:Clone()
			newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
			newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
			newTrail.Parent = char.HumanoidRootPart
		end
	end)
end)

game.Players.PlayerRemoving:Connect(saveData)

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

game.ReplicatedStorage.TrailSelectedRE.OnServerEvent:Connect(function(plr, buying, trail)
	if buying and not plr.OwnedTrails:FindFirstChild(trail.Name) then
		local price = trail.Price.Value
		local coins = plr.leaderstats.Coins
		if price <= coins.Value then
			coins.Value -= price
			trail:Clone().Parent = plr.OwnedTrails
		end
	elseif not buying and plr.OwnedTrails:FindFirstChild(trail.Name) then
		if plr:FindFirstChild("LastTrail") then
			plr:FindFirstChild("LastTrail").Value = trail
		else
			local obj = Instance.new("ObjectValue")
			obj.Parent = plr
			obj.Name = "LastTrail"
			obj.Value = trail
		end
		local char = plr.Character
		if not char or not char:FindFirstChild("HumanoidRootPart") then return end
		for i, child in pairs(char.HumanoidRootPart:GetChildren()) do
			if child:IsA("Trail") then child:Destroy() end
		end
		local newTrail = trail:Clone()
		newTrail.Attachment0 = char.HumanoidRootPart.TrailTop
		newTrail.Attachment1 = char.HumanoidRootPart.TrailBottom
		newTrail.Parent = char.HumanoidRootPart
	end
end)

I only had to modify the one script, an ObjectValue instance is created which stores a reference to the most recently equipped trail, when the player’s character reloads/spawns that object (the trail) is cloned and attached to the player’s character model.

3 Likes

Ok so the script works but the problem is now when the player first spawns in and equips a trail it does not show up until they die. But after they do die the script works flawlessly.

@Forummer’s solution seems to have a CharacterAdded event, so I don’t understand why this wouldn’t work…

Can you screenshot any errors you get please?

In the part where you equip and unequip the trail, just to make sure it works print the boolvalue.
Or you could try

game.Players.CharacterAdded:Connect(function()
-- Some stuff

end)

Welp nvm I tried again in the actually game and not in studio and it work! No errors.

1 Like