roblox studio plr.Name == "" - lua

i'm making a script that detects a person using their name however I can't seem to get it working. Please also point out any mistakes I have done in my script it would help a lot.
game.Workspace:WaitForChild("Console")
print("Waited")
game.Players.PlayerAdded:Connect(function(plr)
print("Connected")
if game.Workspace.Console and plr.Name == "wojciechpa2007" then
local Console = game.Lighting.Console:Clone()
Console.Parent = plr.Startergui
print("Cloned")
elseif
not game.Workspace.Console and plr.Name == "wojciechpa2007" then
plr.Startergui.Console:Destroy()
print("Destroyed")
end
end)

Heyo,
This script has a race-condition in it. Your first line game.Workspace:WaitForChild("Console") will block execution of the rest of your script until the object is loaded, or a timeout is reached.
This means that it is possible that a player could join the game before the script can listen for the game.Players.PlayerAdded signal.
Also StarterGui does not exist on specific player. It exists at the game level and is a bucket that dumps its stuff into a Player's PlayerGui when that player's character loads into the game.
So to fix your script, you could try something like this :
-- right away connect to the PlayerAdded signal
game.Players.PlayerAdded:Connect(function(plr)
print("Player Joined!", plr.Name, plr.UserId)
-- do something special if wojciechpa2007 joins
if plr.Name == "wojciechpa2007" then
print("wojciechpa2007 joined! Adding console!")
-- add the special console into the player's PlayerGui for when they load
local Console = game.Lighting.Console:Clone()
Console.Parent = plr.PlayerGui
end
end)
Some recommendations and things to be careful about here :
It's safer to check a player's UserId than it is to check their name. Roblox lets you change your name, but you UserId is always the same.
Putting something into your StarterGui will make it show up in your PlayerGui the next time your character loads. But if your character is already loaded, you won't see it until the next time you respawn.
If your Console object is some kind of GUI element, make sure that it is parented to a ScreenGui object before you insert it into the Player. Otherwise it just won't show up.
Hope this helps!

Related

Roblox Lua: Issue defining a value in a player's leaderstats folder (no error message)

I have a system in my game where when a player steps on a checkpoint, a Stage value in the leaderboard will go up, and then that value is saved to that player's userId.
I want there to be a button that resets that value back to 0, and this is the code I tried for it.
local textButton = script.Parent
local Players = game:GetService("Players")
textButton.MouseButton1Up:Connect(function()
local player = game.Players.LocalPlayer
local stage = Players:WaitForChild(player):WaitForChild("leaderstats").Stage
if stage.Value > 1 then
stage.Value = 1
end
end)
I've tried debugging it by putting print commands in different places to see where the code gets, and when I try to run print(stage) it does not show anything.
LocalScripts cannot change the value on the server. To change a value once a button is clicked, RemoteEvents should be used.
There is a page documenting about them here: https://create.roblox.com/docs/scripting/networking/remote-events-and-functions
To use a RemoteEvent, first you need to put it in a place that is replicated across the server and the client. A good example of this would be to put it in ReplicatedStorage. After that, you need to set up a script that listens for the .OnServerEvent event of the RemoteEvent. To do this, you need to connect a function. As seen in your script, you already know how to do this. So I will get straight to the point.
On the server, set up a script that listens for .OnServerEvent. Next, on the client, edit your script to fire the client instead of trying to set the value. Go back to the server script, and set the value there. The event also passes the Player object, so you can utilize that to actually reset the value.
TLDR;
LocalScript inside of your TextButton:
local textButton = script.Parent
local Players = game:GetService("Players")
local RemoteEvent = 'RemoteEvent location'
textButton.MouseButton1Up:Connect(function()
RemoteEvent:FireServer()
end)
Server Script in anywhere, preferably ServerScriptService:
RemoteEvent.OnServerEvent:Connect(function(player)
local Players = game:GetService("Players")
local stage = Players:WaitForChild(player):WaitForChild("leaderstats").Stage
if stage.Value > 1 then
stage.Value = 1
end
end)
Good luck!

If a player doesn't own a gamepass, then prompt it via ScreenGUI not working?

I'm trying to make a localscript for a TextButton so that when somebody clicks on it, the script checks if they have the gamepass. If they do, it will do a multitude of other things. But, if the player doesn't have the gamepass, then it will prompt it to them.
Here is the code for my localscript:
local ID = 42076468
local plr = game.Players.LocalPlayer
local MPS = game:GetService("MarketplaceService")
script.Parent.MouseButton1Click:Connect(function()
if MPS:UserOwnsGamePassAsync(plr.UserId,ID) then
-- do stuff
else
MPS:PromptGamePassPurchase(plr.UserId,ID)
end
end)
The problem is that it doesn't prompt the player, even when I remove my conditional statements. This localscript is inside of a TextButton, inside of a Frame, inside of a ScreenGUI.
Any help is deeply appreciated, thanks.
You've made a simple mistake of calling PromptGamePassPurchase(player, gamePassId) the same way as UserOwnsGamePassAsync(userId, gamePassid).
PromptGamePassPurchase expects you to pass in a Player as the first argument, whereas UserOwnsGamePassAsync expects a userId. So all you gotta do is correct the first argument.
MPS:PromptGamePassPurchase(plr, ID)
Also, don't forget to define the callback for the ProcessReceipt event!

What does "attempt to index function with 'Connect'" mean in Roblox?

local Player = game.Players.LocalPlayer
local PlayerCash = Player:WaitForChild("leaderstats"):WaitForChild("Strength")
local Mouse = Player:GetMouse()
local amount = 50
script.Parent.Activate:Connect(function()
game.Players.LocalPlayer.leaderstats.money.Value = game.Players.LocalPlayer.leaderstats.money.Value + amount
end)
I am trying to make a code to give Strength when you click. When I press 'Play' it doesn't work. All it says in the output is
'attempt to index function with 'Connect'.'
The error "attempt to index [type] with [field name]" means that you are incorrectly using something like an object, and you are trying to access some field on it.
In your case, this error is pointing at the line : script.Parent.Activate:Connect.This says that script.Parent.Activate is a function and not a table, and you cannot call Connect on a function. This is just to help us figure out what is wrong with our code.
Since you working with Tools, there is a simple fix. Instead of using the Activate function, you are looking for the Activated event. So just change update that line like this :
script.Parent.Activated:Connect(function()
It connects a function to an event that happened, like this:
local tool = script.Parent
-- It connects the event (the tool being equipped) to a function.
tool.Equipped:Connect(function()
-- CODE
end)
Also, the answer above is how you can fix your problem and here's a shortcut: You have defined "Player" and you could've used it inside the function. Have a great day and God bless everyone here.

Bailing people out of prison in roblox using Remote Events doesn't seem to work properly

Here's the deal. When you get arrested in my game, you get sent to jail. To get out you must be bailed out.
The client sends a request to the server to bail them. Every other part seems to work except this part I believe, however it could be the client side script. Is there anything incorrect about this script? I have checked it for any errors that are obvious to me.
local replicatedStorage = game:GetService('ReplicatedStorage')
local createSystemMessage = replicatedStorage:WaitForChild('CreateSystemMessage')
game.ReplicatedStorage.Bail.OnServerEvent:Connect(function(Player,PlayerToBail)
Player = game.Players:FindFirstChild(Player)
local tab = nil
for i,v in pairs(_G.GlobalData) do
if v.Name == Player.Name then
tab = v
end
end
if PlayerToBail.Team == game.Teams:FindFirstChild("Criminal") then
local Bounty = PlayerToBail.leaderstats.Bounty.Value * 2
if tab.Bank <= Bounty then
tab.Bank -= Bounty
PlayerToBail.leaderstats.Bounty.Value = 0
PlayerToBail.Prisoner.Value = false
PlayerToBail.Team = game.Teams:FindFirstChild("Civilian")
createSystemMessage:FireAllClients((Player.Name .. ' has Bailed ' .. PlayerToBail.Name), Color3.fromRGB(0, 250, 0))
end
end
end)
And the local script which works:
script.Parent.AcceptButton.MouseButton1Click:Connect(function()
local PlayerName = script.Parent.TargetName.Text
game.ReplicatedStorage.Bail:FireServer(PlayerName)
print ("Bail Requested")
end)
I believe the problem occurs with the argument you're passing to the remote event.
In your client script you pass PlayerName as an argument. I'm assuming this is a string of the player's name:
game.ReplicatedStorage.Bail:FireServer(PlayerName)
PlayerName will actually be sent to the parameter "PlayerToBail", which I'm assuming is supposed to be a player object. Keep in mind that Roblox's RemoteEvents automatically pass in the player who fired the remote event as the first argument. So the "Player" parameter of the function connected to your remote event is the actual player object that has the local script that fired the remote event.
Instead, I would fire the remote event like this:
game.ReplicatedStorage.Bail:FireServer()
Since the player you want to bail is automatically passed as an argument, you don't need to add any additional arguments to FireServer. In addition, you would get rid of the "PlayerToBail" parameter in your server script.
Also note, it is unnecessary to have this line of code in your server script:
Player = game.Players:FindFirstChild(Player)
Player is already referring to an object in game.Players. In addition, Player is an object, not a string. So this would not work. You can simply use Player as is for your purposes.
More info on Remote Events: https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events
Please feel free to follow up if you still have issues.
When firing the server it automatically gives a parameter which is the player who sent it. So, you don't have to have the playerName part because after the player parameter is already there and you can get the name from that.

Editting Roblox module execute err

-- This is some of the code made by Roblox themselves:
-- Setup table that we will return to scripts that require the ModuleScript.
local PlayerStatManager = {}
-- Table to hold all of the player information for the current session.
local sessionData = {}
-- Function the other scripts in our game can call to change a player's stats. This
-- function is stored in the returned table so external scripts can use it.
function PlayerStatManager:ChangeStat(player, statName, changeValue)
sessionData[player][statName] = sessionData[player][statName] + changeValue
end
-- Function to add player to the sessionData table.
local function setupPlayerData(player)
sessionData[player] = {Money = 0, Experience = 0}
end
-- Bind setupPlayerData to PlayerAdded to call it when player joins.
game.Players.PlayerAdded:connect(setupPlayerData)
-- Return the PlayerStatManager table to external scripts can access it.
return PlayerStatManager
--------------------------------------------------------------------------------
-- Require ModuleScript so we can change player stats
local PlayerStatManager = require(game.ServerStorage.PlayerStatManager)
-- After player joins we'll periodically give the player money and experience
game.Players.PlayerAdded:connect(function(player)
while wait(2) do
PlayerStatManager:ChangeStat(player, 'Money', 5)
PlayerStatManager:ChangeStat(player, 'Experience', 1)
end
end)
When I run these two script, it run perfectly, adding the print(sessionData[player][statName]) inside the ChangeStat function, but when I removed the game.Players.PlayerAdded:connect(setupPlayerData) part in the module script, it stopped working. I though module script does not execute code without it being called, and if that was the case, shouldn't the game.Players.PlayerAdded:connect(setupPlayerData) part be delay and not function since player's already added, therefore it not firing?
require executes the required code.
If that was not the case you would not be able to get a table through require, as your return PlayerStatManager statement would not be executed.
As a consequence removing
-- Bind setupPlayerData to PlayerAdded to call it when player joins.
game.Players.PlayerAdded:connect(setupPlayerData)
will cause an added player not to be initialized properly. This basically says: when a new player is added, call setupPlayerData.
Where setupPlayerData says: give a new set of stats to player
As you removed that line no player has stats. If you don't have stats you can't increase their values...
So obviously you did not understand what the code did befor you changed it. Therefor you cannot understand why your changes cause problems.
If you change a system you don't understand you can be lucky, but in most cases you will utterly fail.

Resources