I'm currently trying to make a pet shop GUI in my simulator game. I have a pet and this code works in the local script in the text button:
local pet = game.ReplicatedFirst.Part:Clone() local plr = game.Players.LocalPlayer script.Parent.MouseButton1Click:Connect(function() pet.Parent = plr.Character end)
I'm trying to the script so that you need at least one "strength" (leaderstat) for this script to run. This is what I tried but it doesn't seem to work:
local pet = game.ReplicatedFirst.Part:Clone() local plr = game.Players.LocalPlayer script.Parent.MouseButton1Click:Connect(function() if player.leaderstats.rebirths.Value >= 1 then pet.Parent = plr.Character end end)
Can anyone help me?
Alright, while I don't know your exact problem because you haven't provided any output information; I can try and deduce what is wrong and explain how you can move forward and secure your code in the process to help save you from major headaches regarding the client-server model in ROBLOX.
Objects that you put in ReplicatedFirst run, well, absolutely first. You don't store storage objects there. As the contents of ReplicatedFirst replicate to the client before anything else in the game. it is ideal for creating loading GUIs or tutorials. In your case, a pet model does not meet this criteria, so it shouldn't be there. ReplicatedStorage is where you can store references to objects that need to be "Replicated" to the client. Both the client and server can see these objects. In your case however, unless you need to access this model from the client to show in a Viewport for instance, your pet models can be placed in ServerStorage, away from prying eyes. This also helps with lag, as anything placed in ReplicatedStorage will be replicated to the player.
*NEVER TRUST THE CLIENT to do anything regarding sanity checks that are going to give them leverage. The client is a liar, anything they say can and will be used against you. *
Think of me as bank teller and you as the customer. If you told me you had 1million dollars to withdraw, would I just give it to you or would I look you up in the database first? I'm not going to trust you to tell me what you have; I'm going to verify your balance and I'm going to verify you are who you say you are.
When you are asking the player if they enough rebirths to unlock the pet, all a player has to do is change their leaderstats, which can be done very easily. Instead, what you can and should do is keep this check, but then also fire a RemoteEvent to the server that checks again and handles the rest on the server.
LocalScript in your GUI
local LocalPlayer = game.Players.LocalPlayer local leaderstats = LocalPlayer:WaitForChild("leaderstats") local rebirths = leaderstats:WaitForChild('rebirths') local button = script.Parent local PetGiverEvent = game:GetService("ReplicatedStorage"):WaitForChild('PetGiver') local NotificationEvent = game:GetService("ReplicatedStorage"):WaitForChild('Notification') NotificationEvent.OnClientEvent:Connect(function(msg) print ( msg ) end) button.MouseButton1Down:Connect(function() if rebirths.Value >= 100 then PetGiverEvent:FireServer('Dragon') end end)
Script in ServerScriptService
local PetStorage = game:GetService('ServerStorage').Pets local RemoteEvent = game:GetService("ReplicatedStorage").PetGiver local NotificationModule = require ( script.Notification ) local Pets = { ['Dragon'] = { Pet = PetStorage:WaitForChild("Dragon"), Cost = 100 } } local PlayerPets = {} local function Assign(Player, newPet) -- Delete old assigned pet to make way for new pet if PlayerPets[Player.Name] then PlayerPets[Player.Name]:Destroy() end -- Get previous pet name or newPet from Pets local Pet = newPet and Pets[newPet].Pet:Clone() or Pets[PlayerPets[Player.Name].Name].Pet:Clone() -- Give pet Pet.Parent = Player.Character -- Assign pet PlayerPets[Player.Name] = Pet -- SetNetworkOwner erorrs if Parent doesn't exist yet repeat wait() until Player.Character Pet.PrimaryPart:SetNetworkOwner(Player) end RemoteEvent.OnServerEvent:Connect(function(PlayerWhoFired, PetName) assert(PetName, 'Provide a PetName') assert(typeof(PetName) == 'string', 'PetName has to be a string!') local MatchingKey = Pets[PetName] -- is the pet even real? Client could have lied if Pets[PetName] then local leaderstats = PlayerWhoFired:FindFirstChild("leaderstats") local rebirths = leaderstats and leaderstats:FindFirstChild("rebirths") -- Are our rebirths actually >= to the requirement? if rebirths then if rebirths.Value >= MatchingKey.Cost then -- They are, assign the new pet. Assign(PlayerWhoFired, PetName) else -- Are not, notify client they lost the battle NotificationModule.Message(PlayerWhoFired, "You don't have enough") end end else -- Pet isn't real NotificationModule.Message(PlayerWhoFired, 'That pet does not exist') end end) game.Players.PlayerAdded:Connect(function(Player) script.leaderstats:Clone().Parent = Player Player.CharacterAdded:Connect(function(character) -- give them their pet each time they respawn if PlayerPets[Player.Name] then Assign(Player) end end) end) game.Players.PlayerRemoving:Connect(function(Player) -- clean up referance PlayerPets[Player.Name] = nil end)