(Bear with me here, this might be a little confusing) Alright so I'm super new to scripting and trying to figure out how to make this one line of code. What happens is, this server script,
game.Players.PlayerAdded:connect(function(player) local event = Instance.new("Folder") event.Name = "Events" event.Parent = player end)
creates a folder in the local player. Then this server script creates an event within the folder and fires the event when the parent brick is clicked on, which sends a client fire thingy(forgot what they're called) to a local script in StarterPlayerScripts.
game.Players.PlayerAdded:connect(function(player) local click = Instance.new("ClickDetector") click.Parent = workspace.cap local event = Instance.new("RemoteEvent") event.Parent = game.Players.LocalPlayer:WaitForChild("Events") event.Name = "cow" click.MouseClick:connect(function(player) event:FireClient(player) end) end)
This is the local script.
local h = game.Players.LocalPlayer:WaitForChild("Events"):WaitForChild("cow").OnClientEvent:connect(function() local v = game.Players.LocalPlayer:WaitForChild("PlayerData"):WaitForChild("cowss") v.Value = v.Value + 10 local t = game.Players.LocalPlayer.PlayerGui:WaitForChild("cows").Frame.s t.Text = v.Value end)
"cows" is the name of the gui in StarterGui. This whole script thing is supposed to, when you click on a part, add a value to the player's data, then update the gui so that is shows how much you have clicked on it.
When I open it up in the studio, everything works great, but when I open it up in game, nothing works and I get the message 'Infinite yield on Players.Devetious7.Events:WaitForChild("cow")'. If this is a bit too confusing the way I'm explaining it then I could give anyone who is willing to help team building permissions so they could fix it. Any help is appreciated, thanks.
this is due to the difference between studio and the actual game, in studio, the game preloads assets and loads fairly quickly, but in an actual game, there is a fair bit of latency, meaning that the local script that waits for the event "cow" waited a substantial amount of time for the event "cow". Although this is only part of the explanation. The other part is that you never established a maximum wait time, which means that if the event "cow" doesn't exist, the script would never go beyond waiting for the event "cow" and never run any other code. To combat this, you can set a maximum wait time on the WaitForChild() function.
local plr = game.Players.LocalPlayer local h plr:WaitForChild("Events",60):WaitForChild("cow",60).OnClientEvent:Connect(function() local v = plr:WaitForChild("PlayerData",60):WaitForChild("cowss",60) v.Value = v.Value + 10 local t = plr:WaitForChild("cows",60).Frame.s t.Text = v.Value end)
Notes to take away
--WaitForChild() waits forever if no maximum wait time is set --connect is deprecated, the use of Connect is now preferred --[[if you repeatedly use something like game.Players.LocalPlayer, make a variable for that, then use that variable]]
As long as you provide the code and give a general idea of what it's supposed to do, one of us here on SH will gladly help you.
Anyways, you have alot of messy code that you can fix and it'll help you become better at knowing what you're doing.
Your main issue is how you're going about using the Server to Client communication to update the player interface. I'm going to give you a run down of how it should look like and hopefully you can reformat your old code to how it should be.
We'll start with using a Script inside of the part that will be clicked. Make sure you have a remote event inside ReplicatedStorage, and a part in workspace with a click detector inside it.
Script inside part:
--Define ReplicateStorage local RS = game:GetService("ReplicatedStorage") --Define the remote event in RS local event = RS:WaitForChild("RemoteEvent") --ClickDetector inside our part local clickDetector = script.Parent:WaitForChild("ClickDetector") --When the player clicks our part: the server will tell the client to "addPoint" clickDetector.MouseClick:Connect(function(playerThatClicked) event:FireClient(playerThatClicked, "addPoint") --Not sure whether you need to add a point to the player's leaderstats --If you do, you can still do it in here since we're in server side end)
Now we'll insert a local script inside a ScreenGui that can be inside of StarterGui. That way the player spawns with the GUI every time. I'm going to use a TextLabel in ScreenGui to show our points. Our points will be added in an IntValue that we can insert inside the ScreenGui.
Local Script inside a ScreenGui:
--Define ReplicateStorage local RS = game:GetService("ReplicatedStorage") --Define the remote event in RS local event = RS:WaitForChild("RemoteEvent") --Find our textlabel local gui = script.Parent local textLabel = gui:WaitForChild("TextLabel") --Find our intvalue inside ScreenGui local points = gui:WaitForChild("IntValue") --Use a Changed event on points (IntValue) to change our TextLabel's text points.Changed:Connect(function(property) textLabel.Text = property end) --When our remote event is triggered, check the reason and add a point to 'points' event.OnClientEvent:Connect(function(reason) if reason == "addPoint" then points.Value = points.Value + 1 end end)
Notice that FireClient()
takes a player parameter followed by any arguments after that. I'm using an argument of type string value to pass a sort of "Reason" that my client looks out for. If my local script notices the reason is "addPoint" then we'll run the code under it. That way we can reuse the remote event to tell the client to do other things. Like taking away some points.
If somethings wrong with any of my code or you need further explanation let me know.
edit: formatting