Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

:FireServer results in "cant address nil value"?

Asked by 5 years ago

i have this localscript in startergui:

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:FindFirstChild("test")
3mouse = game.Players.LocalPlayer:GetMouse()
4function onF()
5    game.ReplicatedStorage.test:FireServer()
6end
7 
8game.Workspace.Baseplate.Touched:Connect(onF())

and this script in ReplicatedStorage

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:FindFirstChild("test")
3 
4game.ReplicatedStorage.test.OnServerEvent:Connect(function()
5 
6    print("test")
7 
8end)

and, obviously a RemoteEvent in ReplicatedStorage named test.

Thing is, when something touches it just outputs "cant address nil value"

Google hasn't yielded anything about it.

3 answers

Log in to vote
0
Answered by
Ankur_007 290 Moderation Voter
5 years ago

The error is probably at Line 8, where you're trying to set the Baseplate.Touched connection. Touched is an event and events take functions as either an anonymous function:

1Event:Connect(function()
2    -- Function body
3end)

Or as a predefined function

1Event:Connect(foo)

The point to note in the second case is that you have to pass the function and not call it. If you have knowledge about functions returning values, you know that calling foo() will return whatever the function returns or simply nil if nothing is returned. Implementing this in your script we see that

1game.Workspace.Baseplate.Touched:Connect(onF())
2-- is equivalent to doing
3game.Workspace.Baseplate.Touched:Connect(nil)
4-- (since onF() returns nothing)

To fix this simply remove the brackets after onF to prevent calling it:

1game.Workspace.Baseplate.Touched:Connect(onF)

That's how you can solve the error!


On another note, you should use your testevent variable in onF now that you defined it


Feel free to ask any questions you have

0
Now i'm getting: "- Remote event invocation queue exhausted for ReplicatedStorage.test; did you forget to implement OnServerEvent" Even though my Script looks correct. holadivinus 4 — 5y
0
Touched happens to fire repeatedly VERY fast, meaning your onF function is spammed. Thus the remote is repeatedly invoked too fast.Add a debounce to fix the same Ankur_007 290 — 5y
Ad
Log in to vote
0
Answered by 5 years ago

Improvements

Use :WaitForChild() to make sure something exists before using it [since you are using FindFirstChild, if the "child" is not found, the value will be nil]

Use GetService() for the Players Service

Use workspace instead of game.Workspace

You have the local "testevent" that you're not even using where the reference could be made

Issues

If your script is only in ReplicatedStorage, then unless its being cloned into the Workspace or ServerScriptService, it will not be run (if this is the case, place it in the ServerScriptService)

There are no parameters for the "onF" function, so don't include it in the connection, these additional parentheses are not required as they would be in a language like Java.

Revised Local Script

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:WaitForChild("test")
3local mouse = game:GetService("Players").LocalPlayer:GetMouse()
4 
5workspace:WaitForChild("Baseplate").Touched:Connect(function(hit)
6    testevent:FireServer()
7end)

You can keep the connection separate like so:

1local function onF()
2    testevent:FireServer()
3end
4 
5workspace:WaitForChild("Baseplate").Touched:Connect(onF)

but if this is the only place its used, then just connect it directly like in your serverscript

Revised Server Script

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:WaitForChild("test")
3 
4testevent.OnServerEvent:Connect(function()
5    print("test")
6end)
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

I'm gonna try and cover everything, here. So uh, here we go. So, let's start with your local script

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:FindFirstChild("test")
3mouse = game.Players.LocalPlayer:GetMouse()
4function onF()
5    game.ReplicatedStorage.test:FireServer()
6end
7 
8game.Workspace.Baseplate.Touched:Connect(onF())

You have about 2 unused variables, repstorage, and testevent. (Assuming you're using the mouse for something else in the script) If you don't use them, why have them?

I think you got variables mixed up, so here: "A variable is a name you can use to hold a value. In Lua, a variable can have any Data Types, such as a Number or a String." From: https://developer.roblox.com/en-us/articles/Variables

And when you're running a function from a connect it would be :Connect(onF) not :Connect(OnF())

So the correct script here would be

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:FindFirstChild("test")
3 
4function onF()
5    testevent:FireServer()
6end
7 
8game.Workspace.Baseplate.Touched:Connect(onF)

Now, your script/server script

1local repstorage = game:GetService("ReplicatedStorage")
2local testevent = repstorage:FindFirstChild("test")
3 
4game.ReplicatedStorage.test.OnServerEvent:Connect(function()
5 
6    print("test")
7 
8end)

Again, unused variables The correct script here, would be:

1game.ReplicatedStorage.test.OnServerEvent:Connect(function(plr)
2    print("test")
3end)

You probably noticed that in one script, we used the variables, and in the other, we didn't. It doesn't matter for this case.

So, I noticed you didn't check if it was a player that touched it, since even if a part touches it, it would trigger the function.

So, how would you check if it was a player that touched it? Here.

1game.Workspace.Baseplate.Touched:Connect(function(hit) --hit here is a variable of the part that touched it, in this case a body part
2    local hum = hit.Parent:FindFirstChild("Humanoid") --so script.Parent would be the character, and hum here would be the Humanoid.
3    if hum then --If it exists, then:
4        print("a player touched it!")
5    end
6end)

Also, I've also noticed that you're detecting the touch on the client and firing an event to the server, you can skip the whole remote firing thing and detect the touched on the server instead.

So, if we place a script under baseplate it would look something like this:

1script.Parent.Touched:Connect(function(hit)
2    local hum = hit.Parent.FindFirstChild("Humanoid")
3    if hum then
4        print("test")
5    end
6end)

Also, I used a couple different scripting styles as you can notice. In the last one I didn't use a function, functions aren't a necessity but they just makes things neat and tidy. You can read more about functions here: https://developer.roblox.com/en-us/articles/Function I know not the best of explaining for this question, but I tried my best lol. Goodluck!

Answer this question