Hi ScriptingHelpers community,
I saw that this question have been made before but I'll be glad if some of you can answer it anyway so I can understand better what am I doing wrong.
I have this script in order to print on the terminal when the player press a Key Down and the same thing when the Key is Up:
01 | local PlayersService = game:GetService( 'Players' ) |
02 | local LocalPlayer = PlayersService.LocalPlayer |
03 |
04 | Mouse = LocalPlayer:GetMouse() |
05 |
06 | function KeyUp(key) |
07 | if (key = = "q" ) then |
08 | print ( 'Key is Up' ) |
09 | end |
10 | end |
11 |
12 | function KeyDown(key) |
13 | if (key = = "q" ) then |
14 | print ( 'Key is Down' ) |
15 | end |
16 | end |
17 |
18 | Mouse.KeyUp:connect(KeyUp) |
19 | Mouse.KeyDown:connect(KeyDown) |
The problem is that when I run the game with the script it says: - ServerScriptService.Script:4: attempt to index field 'LocalPlayer' (a nil value)
I have the script on the 'ServerScript' folder and I also tried with the 'StarterPlayerScripts' folder but the same error appears. What am I missing?.
I'm new with this hole thing called 'Roblox Scripting' and I don't know a lot of things about the API so I'll be glad if some of you can answer my question.
In the meantime, thank you so much for your attention.
There are two sides to Roblox games. There are the clients, and there is the server. The server doesn't, and shouldn't, handle user input.
Think of this; when the server tried to find a LocalPlayer
, which player does it pick? There may be multiple players connected to the game, and it can't just pick one at random.
Your script works in Studio because everything is ran on your computer locally, and there is no server. In an actual game, that's not the case.
The solution is to use a LocalScript
, in StarterPack
, or somewhere else LocalScripts can run. Then the Local Script will replicate inside the players when they join, and they'll run locally.
Code ran on the client normally doesn't replicate to the server if Network Filtering is enabled.
1 | -- Local Script in StarterPack |
2 |
3 | --// Services |
4 | local Players = game:GetService( "Players" ) -- About the same as game.Players |
5 |
6 | --// Local Variables |
7 | local plr = Players.LocalPlayer |
Now, to get user input you should not use KeyDown
. KeyDown is deprecated. Instead, I recommend UserInputService
.
Here's an example of the finished code:
01 | -- Local Script in StarterPack |
02 |
03 | --// Services |
04 | local Players = game:GetService( "Players" ) |
05 | local UIS = game:GetService( "UserInputService" ) |
06 |
07 | --// Local Variables |
08 | local plr = Players.LocalPlayer |
09 |
10 |
11 |
12 | -- Input Began |
13 | UIS.InputBegan:Connect( function (input) |
14 | if input.KeyCode = = Enum.KeyCode.Q then |
15 | print ( "Q was pressed!" ) |