I have a bug in my Roblox Project. Im very frustrated because it doesnt work as expected. I have a remote event that fires the server from a local script. It gives the parameter "OilBarrel". In the Server script it looks when its fired and then the player picks up the Oil Barrel. In there I have the player and the OilBarrel parameter. When i try to print the OilBarrel in the Server script it says "nil", but in the local script not. Here is the code from the local script:
local WS = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local TakeOilBarrelEvent = RemoteEvents.TakeOilBarrel
local ThrowOilBarrelEvent = RemoteEvents.ThrowOilBarrel
local SpawnOilBarrelEvent = RemoteEvents.SpawnOilBarrel
local plr = Players.LocalPlayer
local char = plr.Character
local torso = char:WaitForChild("LowerTorso")
local mouse = plr:GetMouse()
local OilBarrelGui = script.Parent.Parent.OilBarrelGui
local DropOilBarrel = OilBarrelGui.DropOilBarrel
local debounce = false
local function getTycoon(player)
for _, tycoon in game.Workspace.Tycoons:GetChildren() do
if tycoon:GetAttribute("UserId") == player.UserId then
return tycoon
end
end
end
local function ThrowOilBarrel(OilBarrel)
ThrowOilBarrelEvent:FireServer(OilBarrel)
OilBarrelGui.Enabled = false
debounce = false
end
local function TakeOilBarrel(OilBarrel)
TakeOilBarrelEvent:FireServer(OilBarrel)
OilBarrelGui.Enabled = true
end
SpawnOilBarrelEvent.OnClientEvent:Connect(function()
local Tycoon = getTycoon(plr)
local OilBarrelStation = Tycoon.Decoration.OilBarrelStation.Platform
local OilBarrel = ReplicatedStorage:WaitForChild("OilBarrel")
local OilBarrelClone = OilBarrel:Clone()
OilBarrelClone.Parent = WS:WaitForChild("OilBarrels")
OilBarrelClone.Position = OilBarrelStation.Position + Vector3.new(0, 2, 0)
local OilBarrels = WS:WaitForChild("OilBarrels"):GetChildren()
for _, OilBarrel in ipairs(OilBarrels) do
if OilBarrel.Name == "OilBarrel" then
OilBarrel.ClickDetector.MouseClick:Connect(function(player)
if OilBarrel:FindFirstChild("Weld") then return end
if player == plr then
if debounce then return end
debounce = true
TakeOilBarrel(OilBarrel)
DropOilBarrel.MouseButton1Click:Connect(function()
ThrowOilBarrel(OilBarrel)
end)
mouse.KeyDown:Connect(function(key)
if key == "q" then
ThrowOilBarrel(OilBarrel)
end
end)
end
end)
else
continue
end
end
end)
And here the server script:
TakeOilBarrelEvent.OnServerEvent:Connect(function(player, OilBarrel)
local char = workspace:WaitForChild(player.Name)
local Animate = char:FindFirstChild("Animate")
if Animate then
Animate:Destroy()
end
local OilBarrelAnimation = game:GetService("ReplicatedStorage"):WaitForChild("Animations").OilBarrelAnimation
if char:FindFirstChild("OilBarrelAnimation") == nil then
local OilBarrelAnimationClone = OilBarrelAnimation:Clone()
OilBarrelAnimationClone.Parent = char
end
local torso = char:WaitForChild("LowerTorso")
local weld = Instance.new("Weld")
weld.Parent = OilBarrel
weld.Part0 = OilBarrel
weld.Part1 = torso
OilBarrel.CFrame = torso.CFrame
OilBarrel.Rotation = Vector3.new(0, -180, -90)
OilBarrel.Position = OilBarrel.Position + torso.CFrame.LookVector * 2.2
end)
When i want to pick up the Oil Barrel i get this error: "Attemp to index "nil" with CFrame" This means that the OilBarrel parameter is nil. But how can i fix this?
You have run into an issue with client-server replication. Remember that the server is the authority on objects. When an object is created on the server, its creation is replicated to all clients, and all players can see that object. However, for security reasons, when an object is created on the client, its creation is NOT replicated up to the server.
This means that if you create an object on the client, and then ask the server about that object, the server will have no idea what you're talking about because that object will not exist on the server.
So let's look at your code...
SpawnOilBarrelEvent.OnClientEvent:Connect(function()
local Tycoon = getTycoon(plr)
local OilBarrelStation = Tycoon.Decoration.OilBarrelStation.Platform
local OilBarrel = ReplicatedStorage:WaitForChild("OilBarrel")
local OilBarrelClone = OilBarrel:Clone()
OilBarrelClone.Parent = WS:WaitForChild("OilBarrels")
OilBarrelClone.Position = OilBarrelStation.Position + Vector3.new(0, 2, 0)
Here, the server tells the client to spawn the barrel, and the client creates the barrel. This means that the barrel only exists on that client. So you cannot have server logic interact with that barrel.
The fix is either to...
a) move the contents of the SpawnOilBarrelEvent.OnClientEvent
connection up to the server so that barrels exist for all players. This may have implications on game performance as well as who can interact with the barrels, and you'll need to fix that as well.
or...
b) move the contents of the TakeOilBarrelEvent.OnServerEvent
connection down to the client, and have the animations play on the client. However, other players will not be able to see these animations play, as they will only play on that specific client.