robloxluau

Roblox Studio Bug: Remote Event parameter is nil


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?


Solution

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