local me = script.Parent
local players = game:GetService("Players")
me.Touched:Connect(function(Hit)
local player = players:GetPlayerFromCharacter(Hit.Parent)
if player.TookMoney.Value == true then
player.TookMoney.Value = false
end
end)
It has to make TookMoney.Value = false but it says "attempt to index nil with 'TookMoney' -script:6"
The touched event is triggered on all objects, including non players. Thus players:GetPlayerFromCharacter can return nil. Perform a nil check, e.g.:
me.Touched:Connect(function(Hit)
local player = players:GetPlayerFromCharacter(Hit.Parent)
if player and player.TookMoney.Value == true then
player.TookMoney.Value = false
end
end)
Depending on your setup you may also check if the player has TookMoney.
Related
i was trying to make a button that sets if the player is immortal or no, but it gave me error "Attempt to index nil with 'InLobby'"
Server script
local event = game:GetService('ReplicatedStorage').DieButton
event.OnServerEvent:Connect(function(plr: Player)
print(plr.Name.."has become immortal!")
if game:GetService('Players'):FindFirstChild(plr).InLobby.Value == true then
game:GetService('Players'):FindFirstChild(plr).InLobby.Value = false
else
game:GetService('Players'):FindFirstChild(plr).InLobby.Value = true
end
end)
Client script (In the button gui)
local event = game:GetService('ReplicatedStorage').DieButton
script.Parent.MouseButton1Click:Connect(function()
if script.Parent.Text == "die" then
script.Parent.Text = "dien't"
script.Parent.BackgroundColor3 = Color3.new(1, 0, 0)
else
script.Parent.Text = "die"
script.Parent.BackgroundColor3 = Color3.new(0, 255, 0)
end
event:FireServer()
end)
The error is telling you that game:GetService('Players'):FindFirstChild(plr) is returning nil, meaning that it is not finding the player you are looking for. That is because FindFirstChild expects you to pass it the string name of the child and you have passed it a Player object.
But why are you searching for the player at all? You already have it in the form of the plr variable.
Now, assuming that you have a BoolValue as a child of the player, try this :
local event = game:GetService('ReplicatedStorage').DieButton
event.OnServerEvent:Connect(function(plr: Player)
print(plr.Name.."has become immortal!")
local InLobby = plr.InLobby
InLobby.Value = not InLobby.Value
end)
It keeps returning nil for player and saying that im trying to index a nil with 'WaitForChild' even though I have tried adding a wait command and changing player to 'game.Players.LocalPlayer' I'm new to scripting and I don't know what else to do.
local buyButton = script.Parent
local player = game:GetService("Players").LocalPlayer
local multiplier = player:WaitForChild("Multiplier")
buyButton.MouseButton1Up:Connect(function()
if multiplier.Value == 0 then
multiplier.Value = 1
end
end)
Instead of local player = game:GetService("Players").LocalPlayer you want to do:
local players = game:GetService("Players")
local player = players.localplayer
So, Im tring to make a Mind Control script inside of Roblox. Im using the local script so i can use the UserInputServer Module. But When I Run It(Its inside of StartGui), I doesn't give any output. Here is the source:
--Made By BioShot!--
local UIS = game:GetService("UserInputService")
local Enabled = false
local Active = false
game.Players.PlayerAdded:Connect(function(plr)
print("Player Added!")
UIS.InputBegan:Connect(function(input)
if(input['KeyCode'] == Enum['KeyCode']["E"]) then
if(Enabled == true) then
--Rase Player/Dummy/NPC
local Mouse = plr:GetMouse()
Active = true
while(Active == true) do
local Enemy = Mouse["Target"]
print(Enemy)
Enemy.CFrame = Enemy.CFrame + CFrame.new(0,1,0)
wait(0.5)
end
else
--Drop Player/Dummy/NPC
end
end
end)
UIS.InputEnded:Connect(function(input)
if(input['KeyCode'] == Enum["KeyCode"]["F"]) then
Enabled = true
print("Enabled.")
end
if(input['KeyCode'] == Enum["KeyCode"]["E"]) then
Active = false
end
end)
end)
The statements are only printed after game.Players.PlayerAdded:Connect(function(plr) detects a player being added. Due to the code running in a LocalScript, the player will have already been added by the time the script starts waiting for players. If a second player joins the game, "Player Added!" will indeed be printed in the first player's console.
The player can instead be indexed by using local plr = game:GetService("Players").LocalPlayer.
The script still errors when the player's mouse is pointing to nothing and when trying to change the Enemy's position, but these can be easily fixed. The script then lifts objects upwards by hovering over them and pressing E.
Final code:
--Made By BioShot!--
local UIS = game:GetService("UserInputService")
local Enabled = false
local Active = false
local plr = game:GetService("Players").LocalPlayer
print("Player Added!")
UIS.InputBegan:Connect(function(input)
if(input['KeyCode'] == Enum['KeyCode']["E"]) then
if(Enabled == true) then
--Rase Player/Dummy/NPC
local Mouse = plr:GetMouse()
Active = true
while(Active == true) do
local Enemy = Mouse["Target"]
if Enemy then --Make sure the player's mouse isn't pointing to nothing
print(Enemy)
Enemy.CFrame += Vector3.new(0,1,0)
end
task.wait(0.5) --More accurate than wait(0.5)
end
else
--Drop Player/Dummy/NPC
end
end
end)
UIS.InputEnded:Connect(function(input)
if(input['KeyCode'] == Enum["KeyCode"]["F"]) then
Enabled = true
print("Enabled.")
end
if(input['KeyCode'] == Enum["KeyCode"]["E"]) then
Active = false
end
end)
For a bit of context, I'm making a Tycoon on Roblox to test my knowledge in lua. Everything was working fine until I tried making leaderstats. The first script, which is what makes the Tycoon
function, is here:
local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
local OwnerValue = TycoonInfo:WaitForChild("Owner")
local Buttons = script.Parent:WaitForChild("Buttons")
local Purchases = script.Parent:WaitForChild("Purchases")
local Objects = {}
function validateHitByOwner(Hit)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value== Player then
return true
end
end
return false
end
for i,v in pairs(Buttons:GetChildren()) do
local Object = Purchases:FindFirstChild(v.Object.Value)
if Object then
Objects[Object.Name] = Object:Clone()
Object:Destroy()
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function()
v.Button.Transparency = 1
v.Button.BillboardGui.Enabled = false
v.Button.CanCollide = false
if Purchases:WaitForChild(v.Dependency.Value,90000) then
v.Button.Transparency = 0
v.Button.CanCollide = true
v.Button.BillboardGui.Enabled = true
end
end))
end
local DB = false
v.Button.Touched:Connect(function(Hit)
if validateHitByOwner(Hit)then
if DB == false then
DB = true
if v.Button.Transparency == 0 then
local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
if Purchased then
warn("Purchased")
else
warn("Can't purchase")
end
end
DB = false
end
end
end)
end
end
function DoPurchase(Hit,Button,Cost,Object)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value == Player then
local name = game.Players:GetChildren()
local CashValue = game.Players.name.leaderstats.Cash -- Error here
if CashValue then
if CashValue.Value >= Cost then
CashValue.Value = CashValue.Value - Cost
Object.Parent = Purchases
Button:Destroy()
return true
end
end
end
end
return false
end
The next script, which makes the leaderboard and assigns a player that has recently joined to a random available Tycoon, is here:
function FindEmptyTycoon()
for i,v in pairs(workspace.Tycoons:GetChildren()) do
if v.TycoonInfo.Owner.Value == nil then
return v
end
end
return nil
end
game.Players.PlayerAdded:Connect(function(Player)
local Tycoon = FindEmptyTycoon()
Tycoon.TycoonInfo.Owner.Value = Player
local stats = Instance.new("Folder",Player)
stats.Name = "leaderstats"
local Cash = Instance.new("IntValue",stats)
Cash.Name = "Cash"
end)
And then, the script that is stored in all purchasable items to give the Player money, is here:
function giveCash(player)
wait(3.33)
local Cash = player.leaderstats.Cash
Cash.Value = Cash.Value + 2
end
By the way, these scripts are versions of the original scripts that I've been trying to edit so they can actually work, and I think I've been getting close to fixing the errors. The original scripts can be found here (in order of appearance):
local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
local OwnerValue = TycoonInfo:WaitForChild("Owner")
local Buttons = script.Parent:WaitForChild("Buttons")
local Purchases = script.Parent:WaitForChild("Purchases")
local Objects = {}
function validateHitByOwner(Hit)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value== Player then
return true
end
end
return false
end
for i,v in pairs(Buttons:GetChildren()) do
local Object = Purchases:FindFirstChild(v.Object.Value)
if Object then
Objects[Object.Name] = Object:Clone()
Object:Destroy()
if v:FindFirstChild("Dependency") then
coroutine.resume(coroutine.create(function()
v.Button.Transparency = 1
v.Button.BillboardGui.Enabled = false
v.Button.CanCollide = false
if Purchases:WaitForChild(v.Dependency.Value,90000) then
v.Button.Transparency = 0
v.Button.CanCollide = true
v.Button.BillboardGui.Enabled = true
end
end))
end
local DB = false
v.Button.Touched:Connect(function(Hit)
if validateHitByOwner(Hit)then
if DB == false then
DB = true
if v.Button.Transparency == 0 then
local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
if Purchased then
warn("Purchased")
else
warn("Can't purchase")
end
end
DB = false
end
end
end)
end
end
function DoPurchase(Hit,Button,Cost,Object)
if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
if Player and OwnerValue.Value == Player then
local CashValue = game.ServerStorage.PlayerCash:FindFirstChild(Player.Name)
if CashValue then
if CashValue.Value >= Cost then
CashValue.Value = CashValue.Value - Cost
Object.Parent = Purchases
Button:Destroy()
return true
end
end
end
end
return false
end
function FindEmptyTycoon()
for i,v in pairs(workspace.Tycoons:GetChildren()) do
if v.TycoonInfo.Owner.Value == nil then
return v
end
end
return nil
end
game.Players.PlayerAdded:Connect(function(Player)
local Tycoon = FindEmptyTycoon()
Tycoon.TycoonInfo.Owner.Value = Player
local stats = Instance.new("BoolValue",Player)
stats.Name = "leaderstats"
stats.Parent = game.ServerStorage
local Cash = Instance.new("IntValue",stats)
Cash.Name = Player.Name
Cash.Value = 0
Cash.Parent = game.ServerStorage.PlayerCash
end)
local amount = 2
local timedelay = 2.33
local currencyname = "Cash"
wait(1)
while true do
wait(timedelay)
for i,v in pairs(game.ServerStorage.PlayerCash:GetChildren()) do
if v:FindFirstChild("leaderstats") and v then
v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
end
end
end
local name = game.Players:GetChildren()
Why do you store the list of Players's children in a variable called name? This function returns a table. name would be more suitable for a string.
local CashValue = game.Players.name.leaderstats.Cash -- Error here
game.Players is https://developer.roblox.com/en-us/api-reference/class/Players
I cannot make sense of game.Players.name and even less of game.Players.name.leaderstats
Did you mean Player.leaderstats?
I would expect an error message for Players.name.leaderstats before facing an error for game.Players.name.leaderstats.Cash
name is not a Property of Players so you should not be allowed to index Players.name
I'm no Roblox expert but from what I see your code is so off that you really should start with simple tutorials rather than with fixing this code.
I think you should start over and make sure you understand how Instance.new is used properly and such things.
Using better variable names will also help.
I am working on a script for a map of a game that I will be making. It is kind of like the chaser system in s4 league.
My problem is that once everybody has their "waschaser" set to true, the script should issue a "close map" notice, but once everybody has been chaser, nothing happens and I cant figure out why.
Here is how my table is set up
chaserdb_players = { }
chaserdb_players[charname] = { score = 0, death = 0, kill = 0, waschaser = false }
Now once the map has started, it will search for the next available person with waschaser = false.
for characterName,i in next, chaserdb_players do
if (i.waschaser == false) then
local player = getPlayerByName(characterName, map_copy)
if (player ~= nil) then
addChaserState(player)
break
end
end
end
in the addChaserState(player) function it switches the waschaser = true for that character.
What I am having issues with is that once everybody in the map has their waschaser = true, I need a system notice to start, which i have attempted by doing
for characterName,i in next, chaserdb_players do
if (i.waschaser == false) then
local player = getPlayerByName(characterName, map_copy)
if (player ~= nil) then
addChaserState(player)
break
end
else
Notice("All players have been chaser! The map will close in 30 seconds!")
map_close = true
end
end
here is the getPlayerByName function
function getPlayerByName(name, map_copy)
BeginGetMapCopyPlayerCha(map_copy)
for i = 0 , chaserdb_playercount - 1 , 1 do
local player = GetMapCopyNextPlayerCha ( map_copy )
if (player == 0 or player == nil) then
return nil
else
local playerName = GetChaDefaultName(player)
if (playerName == name) then
return player
end
end
end
end
But that does not work.
Can anybody help? If you need more information feel free to let me know and I will add it.
Move your notice outside the for loop. And use a boolean flag to check for any possible errors:
local bFlag = true
for i,characterName in next, chaserdb_players do
if (characterName.waschaser == false) then
local player = getPlayerByName(i, map_copy)
if (player ~= nil) then
addChaserState(player)
break
end
else
bFlag = false
end
end
if bFlag then
Notice("All players have been chaser! The map will close in 30 seconds!")
map_close = true
end
Slightly more idiomatically:
local allChased = true
for name, character in pairs(chaserdb_players) do
if not character.waschaser then
local player = getPlayerByName(name, map_copy)
if player then
addChaserState(player)
break
end
else
allChased = false
end
end
if allChased then
Notice("All players have been chaser! The map will close in 30 seconds!")
map_close = true
end
Wrapping that in a function works well:
function nextChaser()
for name, character in ipairs(chaserdb_players) do
if not character.waschaser then
local player = getPlayerByName(name, map_copy)
if player then
return player
end
end
end
end
local player = nextChaser()
if player then
addChaserState(player)
else
Notice("All players have been chaser! The map will close in 30 seconds!")
map_close = true
end