I am trying to make a screenGui button that will play a sound inside of their character if they have a badge or prompts marketplace purchase if they don't. The issue that I am getting is that I think Guis need to use localscripts while "userhasbadge" needs to be in a script. I tried "playerownsasset" but I can't get it work. The output recognizes the badge and tells me to use "userhasbadge". Here is just what I've tried and can't get to work. Please excuse the incorrect formatting; I'm pretty inexperienced.
--LocalScript inside of ScreenGui.TextButton -- setup local variables local buyButton = script.Parent local productId = 1280923639 -- when player clicks on buy brick prompt him/her to buy a product buyButton.MouseButton1Click:connect(function() if game:GetService("MarketplaceService"):PlayerOwnsAsset(game.Players.LocalPlayer, productId) == false then game:GetService("MarketplaceService"):PromptProductPurchase(game.Players.LocalPlayer, productId) else game.Players.LocalPlayer.Character.Health = 0 end end)
Great question, Local scripts and Server scripts are two diffrent things, luckly there is a sort of work around this whole problem.
and according to the Robox Wiki API:Class/BadgeService/UserHasBadge
it says that this should be called from a script as opposed to a local script, here's a quote
This item should be used with a Script (As opposed to a LocalScript) in order to work as expected in online mode.
This method cannot be used in Edit mode. It should only be used from an online game server.
That being said you can easily avoid said problem with a script on the server side to check to see if they own said badge then reply back, you'll need a remote event for this.
P.S I've made a few changes to your initial code, but there should be a way to query the server and get a response and continue your code besides this.
P.P.S: You'll need to create a RemoteEvent
in ReplicatedStorage
.
Server Code:
Local BS = game:GetService("BadgeService") Local event = game.ReplicatedStorage:WaitForChild("RemoteEvent") -- scripts load faster than objects event.OnServerEvent:Connect(function(plr, ...) local tuple = {...} -- info recieved if tuple[1] == "HasBadgeRequest" then if BS:UserHasBadge(plr.UserId, tuple[2]) then -- plr = player, tuple[2] = info sent game:FireClient(plr, "HasBadge", tuple[2]) -- send has response else -- if they don't game:FireClient(plr, "NoBadge", tuple[2]) -- send doesn't have response end end end)
LocalScript code:
--LocalScript inside of ScreenGui.TextButton -- setup local variables local buyButton = script.Parent local productId = 1280923639 event = game.ReplicatedStorage:WaitForChild("RemoteEvent") -- incase it doesn't exist and somehow gets created later. local BadgesHas = {} -- empty table for badges user has. local BadgesNo = {} -- empty table for badges user doesn't have event:FireServer("HasBadgeRequest", 0000) -- request info on badge to server (HasBadgeRequest, BadgeID) -- Clone this and replace 0000 with a different badge ID as needed.... -- call back from the server event.OnClientEvent:Connect(function(...) -- server doesn't send back 'plr' only '...' local tuple = {...} if tuple[1] == "HasBadge" then table.Insert(BadgesHas, tuple[2]) end if tuple[1] == "NoBadge" then table.Insert(BadgesNo, tuple[1]) -- more friendy method if you have multiple badges to check for in the future -- you know perhaps NoBadge isn't even needed.... idk really end end) -- when player clicks on buy brick prompt him/her to buy a product buyButton.MouseButton1Click:connect(function() local badge = false local badgeID = 000 -- badge id here for i,v in pairs(BadgesHas) do if v == badgeID badge = true end end for i,v in pairs(BadgesNo) do if v == badgeID then badge = false -- incase something messed up make badge false end end if badge == false then game:GetService("MarketplaceService"):PromptProductPurchase(game.Players.LocalPlayer, productId) else game.Players.LocalPlayer.Character.Health = 0 end end)
what I did was create a method encase you want to have multiple badge checks in one script. the script asks the server if the user has a badge and returns a response, from there the script saves this response in the correct table, this may not be the best method as others may know of a different ones, but this is the only one I could think of.
(Edit: Fixed up version for the asker)
--LocalScript inside of ScreenGui.TextButton -- setup local variables local buyButton = script.Parent local productId = 1280923639 event = game.ReplicatedStorage:WaitForChild("RemoteEvent") -- incase it doesn't exist and somehow gets created later. local PassHas = {} -- empty table for badges user has. local PassNo = {} -- empty table for badges user doesn't have event:FireServer("HasPassRequest", 0000) -- request info on badge to server (HasBadgeRequest, BadgeID) -- Clone this and replace 0000 with a different badge ID as needed.... -- call back from the server event.OnClientEvent:Connect(function(...) -- server doesn't send back 'plr' only '...' local tuple = {...} if tuple[1] == "HasPass" then table.insert(PassHas, tuple[2]) end if tuple[1] == "NoPass" then table.insert(PassNo, tuple[1]) -- more friendy method if you have multiple badges to check for in the future -- you know perhaps NoBadge isn't even needed.... idk really end end) -- when player clicks on buy brick prompt him/her to buy a product buyButton.MouseButton1Click:connect(function() local pass = false local PassID = 000 -- badge id here for i,v in pairs(PassHas) do if v == PassID then pass = true end end for i,v in pairs(PassNo) do if v == PassID then pass = false -- incase something messed up make badge false end end if pass == false then game:GetService("MarketplaceService"):PromptProductPurchase(game.Players.LocalPlayer, productId) else game.Players.LocalPlayer.Character.Health = 0 end end)
server side
local mps = game:GetService("GamePassService") local event = game.ReplicatedStorage:WaitForChild("RemoteEvent") -- scripts load faster than objects event.OnServerEvent:Connect(function(plr, ...) local tuple = {...} -- info recieved if tuple[1] == "HasPassRequest" then if mps:PlayerHasPass(plr, tuple[2]) then -- plr = player, tuple[2] = info sent event:FireClient(plr, "HasPass", tuple[2]) -- send has response else -- if they don't event:FireClient(plr, "NoPass", tuple[2]) -- send doesn't have response end end end)