I'm creating a tower defense game and for some reason the defense argument I'm sending to the remote event to place the defence is nil.
Local script under a button:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local button = script.Parent
local mouseDown = false
button.MouseButton1Up:Connect(function() -- when the player presses the button to add a defence
button.Parent.Tip.Visible = true -- a text label
repeat task.wait() until mouseDown -- waits until the player clicks an area on the map
local defense = game.ReplicatedStorage.Defenses.Defense:Clone() -- sets a variable to defense instance
game.ReplicatedStorage.Events.AddDefence:FireServer(defense, mouse.Hit.Position) -- fires the remote that should build the defence
print(defense.Name) -- prints defence and not nil
button.Parent.Tip.Visible = false -- hides the text label
end)
mouse.Button1Up:Connect(function() mouseDown = false end)
mouse.Button1Down:Connect(function() mouseDown = true end)
Script in server script storage:
local events = game.ReplicatedStorage.Events
events.AddDefence.OnServerEvent:Connect(function(_, defense, mousePos) -- when the event fires
print(_, defense, mousePos) -- printed my username, nil and the mouse position
defense.Parent = workspace.Defenses -- supposed to parent the defence to a folder in workspace (doesn't work since the defence is nil)
defense.Position = Vector3.new(math.floor(mousePos.X/8+0.5)*8, 6, math.floor(mousePos.Z/8+0.5)*8)-- supposed to position the defence (doesn't work again)
end)
Something to keep in mind is that changes made to the world in a LocalScript are invisible to all other players and the server. To be specific, the changes are not replicated to other players.
In your LocalScript, you have :
button.MouseButton1Up:Connect(function()
...
local defense = game.ReplicatedStorage.Defenses.Defense:Clone()
You have created this Defense
clone in a LocalScript, but then tried to tell the server to access it. In the server's eyes, this object does not exist.
If you want this object to appear for everyone, then the server is the one that must create it. Like this :
local function snapToNearest(val, gridSize)
return math.floor((val / gridSize) + 0.5) * gridSize
end
events.AddDefence.OnServerEvent:Connect(function(player, mousePos)
local GRID_SIZE = 8
-- create the defense object where the player clicked
local defense = game.ReplicatedStorage.Defenses.Defense:Clone()
defense.Parent = workspace.Defenses
defense.Position = Vector3.new(snapToNearest(mousePos.X, GRID_SIZE), 6, snapToNearest(mousePos.Z, GRID_SIZE))
end)
Then just update your LocalScript :
button.MouseButton1Up:Connect(function()
-- tell the server to create the defense
button.Parent.Tip.Visible = true -- a text label
game.ReplicatedStorage.Events.AddDefence:FireServer(mouse.Hit.Position)
button.Parent.Tip.Visible = false
end)