Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How to use "UserhasBadge" from a GUI?

Asked by 6 years ago

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)

1 answer

Log in to vote
0
Answered by 6 years ago
Edited 6 years ago

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)






Ad

Answer this question