Clone a tool that only the player can see, pick up, and use

  1. What do you want to achieve?
    I want to clone a tool via a gui that only the player can see and pick up.

  2. What is the issue?
    I have figured out the method outlined below, but have serious doubts that it’s the best way to go about accomplishing this.

I want to create a tool that is parented to the workspace when the player clicks on a GUI. The tool should be able to be picked up and only be seen by the player that clicked on the GUI. Please read my method for accomplishing this below and let me know if this is or isn’t the best way to get this done.

First, I’ll have a LocalScript that runs when the GUI is clicked. The LocalScript will clone a tool from ReplicatedStorage and parent it to the workspace. I clone from ReplicatedStorage using a LocalScript, instead of using a RemoteEvent because I want the tool to be only seen by the player who clicked on the GUI.

Since this tool will have all of it’s scripts deactivated and won’t be able to be picked up, I will need to also fire a RemoteEvent that will clone a corresponding transparent and noncollideable part from ServerStorage and place it in the same location as the tool.

This part will have a script running a touch event that will check if the player touches the part, and thus the cloned tool. However, since I want this script to run only if the player who created it touches it, I will parent an intValue to the part which will store the player’s userId. Then the touch script will check if the humanoid that touches the part has the same userId as the creator of the part.

Only then will the part run code that will clone the tool again from ServerStorage and parent it to the player’s backpack. This same script will also destroy the deactivated tool and the invisible touch part.

**Intuition tells me that this is not the best way to accomplish this.

Don’t have much time. You can either set the transparency to 0 on the server, then set it to 1 on the client, or you can use LocalTransparencyModifier for baseparts. If you do either of these things then you need a checking script on the server to make sure the people who can see the tools are the only ones picking it up. GTG.

- PseudoPerson

I am confused on how you would change the transparency on the client.

Would you have a LocalScript run when player loads and wait for that tool, then when it appears, change it’s transparency?

Yup. What I would do is add a tag to the item on the server with the CollectionService then use the GetInstanceAddedSignal function/event to wait for items on the client. When the client gets an item, it checks if it should make the model visible (invisible on the server) then does. Another option is just adding the tools to a folder in the workspace and use the child added signal to do the same thing.

The following is how I coded it. Thanks to PseudoPerson for getting me off of the dead-end I was on and pointed in the right direction.


Originally, following PsuedoPerson’s advice, I tried placing the tool into ServerStorage and placing a LocalScript that was triggered by a gui button press. This LocalScript cloned the tool and placed it into the workspace. When cloning the tool, an IntValue is inserted into the tool whose value is set to the player who pressed the button’s UserId. The tool has a script that starts running when it’s placed into the workspace that checks if the player’s UserId is equal to the IntValue placed in the tool. If it’s not, the tool is destroyed.

This worked to some extent in that the when the tool is placed into the world by Player_1, it doesn’t exist for Player_2. However, there is a problem when viewing the game from Player_1 and moving Player_2 over the tool, Player_2 picks up the tool! However, in Player_2’s game, he’s not carrying the tool.


After some thought, I combined my previous “solution” to my current “solution” to create an actual solution. I will now describe the actual solution.


I placed the tool in ServerStorage, along with a corresponding part with the appearance of the tool but which is not a tool. When the gui button is pressed by Player_1, a copy of the part that looks like the tool is placed into the workspace. When this part is copied, the UserId of the player in the form of an IntValue is parented to the part.

To prevent the other players from seeing the copied part, I placed a LocalScript in StarterCharacterScripts that waits for this part to be added to the workspace. Once it is, the script checks if the player’s UserId matches the added part’s IntValue. If not, the part is destroyed. This causes the part to not appear in the other player’s workspace.

Lastly, the copied part has a script that detects touch by players. When a player touches the part, the script again checks if the player’s UserId matches the UserId in the IntValue, and only creates a copy of the tool which is parented to the player’s backpack if they match. This prevents other players from picking up the tool when they step over it in the player who created the tool’s game.

This is a solution that doesn’t allow the players who didn’t press the gui button to see the tool, nor pick it up in their games. This also doesn’t allow the other players to pick up the tool in the creator of the tool’s game.


This is the Gui code:

local function onAcceptclick()
    RemoteEvent:FireServer(ranNum)
end

This is the RemoteEvent code:

local function onCreatePart(plr)
    --Clone tool
	local Tool = game.ServerStorage:WaitForChild("Tool"):Clone()
	Tool.Parent = game.Workspace
	
	--Insert the UserId into the HandlePart
	local userId = Instance.new('IntValue')
	userId.Name = 'UserId'
	userId.Value = plr.UserId
	userId.Parent = Tool
end

-- Call "onCreatePart()" when the client fires the remote event
remoteEvent.OnServerEvent:Connect(onCreatePart)

This is the code in the tool:

local ToolModel = script.Parent
local Players = game:GetService("Players")

local function onTouch(touched)
    if touched.Parent:IsA("Model") and touched.Parent:FindFirstChild("Humanoid") then
        local Player = Players:GetPlayerFromCharacter(touched.Parent)
		
        if Player then
            if Player.UserId == ToolModel.UserId.Value then
				ToolModel:Destroy()
				
				local Tool = game.ServerStorage:WaitForChild("Tool"):Clone()
				Tool.Parent = Player.Backpack
				
				Player.Character.Humanoid:EquipTool(Tool)
			end
		end
	end
end

ToolModel.Touched:Connect(onTouch)

Finally, here is the LocalScript in StarterCharacterScripts:

local plr = game:GetService("Players").LocalPlayer

--Waiting for the Tool Model
workspace.ChildAdded:Connect(function(ToolModel)
	if ToolModel.Name == "ToolModel" then
		local ToolModelUserId = ToolModel:WaitForChild("UserId").Value

		if plr.UserId ~= ToolModelUserId then
			ToolModel:Destroy()
		end
	end
end)

And that’s it!

1 Like