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 4 years ago

i have this localscript in startergui:

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:FindFirstChild("test")
mouse = game.Players.LocalPlayer:GetMouse()
function onF()
    game.ReplicatedStorage.test:FireServer()
end

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

and this script in ReplicatedStorage

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:FindFirstChild("test")

game.ReplicatedStorage.test.OnServerEvent:Connect(function()

    print("test")

end)

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
4 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:

Event:Connect(function() 
    -- Function body
end)

Or as a predefined function

Event: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

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

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

game.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 — 4y
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 — 4y
Ad
Log in to vote
0
Answered by 4 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

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:WaitForChild("test")
local mouse = game:GetService("Players").LocalPlayer:GetMouse()

workspace:WaitForChild("Baseplate").Touched:Connect(function(hit)
    testevent:FireServer()
end)

You can keep the connection separate like so:

local function onF()
    testevent:FireServer()
end

workspace: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

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:WaitForChild("test")

testevent.OnServerEvent:Connect(function()
    print("test")
end)
Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

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

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:FindFirstChild("test")
mouse = game.Players.LocalPlayer:GetMouse()
function onF()
    game.ReplicatedStorage.test:FireServer()
end

game.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

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:FindFirstChild("test")

function onF()
    testevent:FireServer()
end

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

Now, your script/server script

local repstorage = game:GetService("ReplicatedStorage")
local testevent = repstorage:FindFirstChild("test")

game.ReplicatedStorage.test.OnServerEvent:Connect(function()

    print("test")

end)

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

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

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.

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

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:

script.Parent.Touched:Connect(function(hit)
    local hum = hit.Parent.FindFirstChild("Humanoid")
    if hum then
        print("test")
    end
end)

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