How do I move specific objects around using a TextButton, but using the TextButton's name to find the object to move?

Hello, as the title describes, I am trying to use a textbutton mousebutton1click function to move objects around, but only objects with the name of the textbutton. (for an inventory system, if that helps)
I currently get this error:

Players.10festive11.PlayerGui.Main.InventoryButton.InvHandler.Item.LocalScript:7: attempt to index nil with 'FindFirstChild'

and this is the code:

local item = script.Parent
local rem = game.ReplicatedStorage.InventoryCheckRemote
local player = game:GetService("Players")
local inv = player:FindFirstChild("Inventory")

item.MouseButton1Click:Connect(function(item)
	if inv:FindFirstChild(script.Parent.Name) then
		inv:FindFirstChild(script.Parent.Name)
		rem:FireServer(item)
	end
end)
local rem = game.ReplicatedStorage.InventoryCheckRemote

rem.OnServerEvent:Connect(function(item)
	item.Parent = game:GetService("Players")[item.Parent.Parent.Name].Inventory
end)

I figured that using a remote would be necessary as moving objects on the client wouldn’t replicate to the server and across all clients.

Thank you for any replies

just bumping for a reply, very stuck on this

Your error states that you’re trying to index nil with FindFirstChild on line 7. Where are you using FindFirstChild?

	if inv:FindFirstChild(script.Parent.Name) then

The error is essentially telling you that the variable inv is nil. Lets look at how inv is being declared

local inv = player:FindFirstChild("Inventory")

Remember that FindFirstChild will return nil if the child is not found when you call it. I imagine that Inventory is an instance that you are parenting to the player under a game.Players.PlayerAdded event, so it is possible that the client script has run before it could be parented. In this case, you should be using WaitForChild instead, to guarantee that Inventory exists (and if not, it will warn you after a few seconds).

Then, there are few other issues with your code that I can see. First of all, you are not getting the local player instance, but instead the Players service, which is essentially the container of the player instances. You should be getting the local player like this:

local player = game.Players.LocalPlayer

Also, MouseButton1Click doesn’t return any arguments, when you are doing

item.MouseButton1Click:Connect(function(item)

you will be overwriting the item variable in the scope of this function to be nil, so you should remove the item argument inside of the function.

Now, judging by your error, I can see that your script is at Players.10festive11.PlayerGui.Main.InventoryButton.InvHandler.Item.LocalScript, so your item variable (as defined on the first line) is a UI element, which the server will not have reference of. Then, if you are passing this item variable to the server, the server will read it as nil. Instead, try to pass item.Name, so the server will have the name of the item it is trying to look for in the player’s inventory

Also, remember that the first argument of OnServerEvent will be the player that send the remote, so your function should look more like

rem.OnServerEvent:Connect(function(player, itemName)
	local inv = player:WaitForChild("Inventory")
	local item = inv:FindFirstChild(itemName)
	if not item then
		-- though your code makes sure itemName exists, remotes can be called maliciously
		-- so validate that the inventory item exists
		return
	end
	
	-- TODO: do something with item
end)
2 Likes

hey! thank you for the very detailed reply.
i appreciate the solution as well as the various pieces of information you gave on how to improve my code as a whole as well as fix the issue

it works now, and i do understand it quite well.
thank you!! have a great day

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.