Showing a GUI on a clicked players screen when having a tool equipped

I am trying to make a script inside of a tool called “Paranoia.” When you have a tool equipped and click on a player, the target player you clicked on gets a gui from ReplicatedStorage which creates the “paranoia effect.”

I attempted to make it as both a LocalScript and a Script with no luck. I have already premade the gui and some other devforum posts have it so it creates the gui via Instance.new(“ScreenGui”) which I don’t want. I am not sure if this maybe has to go through a RemoteEvent to make it work but after checking around, I’ve seen different solutions/scenarios but not really for what I need.

local tool = script.Parent
local gui = game:GetService("StarterGui"):WaitForChild("ScreenGui")

tool.Activated:Connect(function()
	local mouse = game.Players.LocalPlayer:GetMouse()
	local target = mouse.Target
	if target and target.Parent:FindFirstChild("Humanoid") then
		local player = game.Players:GetPlayerFromCharacter(target.Parent)
		if player then
			gui.Enabled = true
			wait(5)
			gui.Enabled = false
		end
	end
end)

image

You need to fire an event when tool is activated (if target player is found), send the target player with the event (all of this is done in a localscript). Then have a script which listens to the event and when its called, check if the target player exists, if yes then clone the gui and place it inside the PlayerGui of the target player. Something like this should work:

--local script
if player then
    event:FireServer(player)
end

--server script
local gui = --path to the gui

event.OnServerEvent:Connect(function(player,targetplayer)
      if game.Players:FindFirstChild(targetplayer) then
             local newgui = gui:Clone()
             newgui.Parent = targetplayer.PlayerGui
      end
end)

I’m guessing these are the placements of each of those scripts? If so, I’ve tried it and it doesn’t work with no output error. If not, can you elaborate?


You put the wrong event name in the server script, also if it still doesnt work it never hurts to put some prints in the code to see where exactly the code fails!

I just realized that wording error. However, when changing it and using the print statements, it seems the event is clearly firing when the tool is activated but the server side isn’t being received, otherwise it would’ve printed “cloned, moving to target”.



Are you sure that isnt just the client output? Put one print outside of the if statement in the server script to see if it is receiving anything, also print targetplayer to see if its actually sent. If it works but still isnt cloning try putting :FindFirstChild(targetplayer.Name) instead.

Client sided is firing when the tool is clicked on the player but targetplayer isn’t being received. Also did try :FindFirstChild(targetplayer.Name) but it returned errors that broke it entirely.

Hm not quite sure why it doesnt work, maybe try sending mouse.Target or player.Name to the server instead and on the server get player same way you did it in a local script (for target) or by doing local player = game.Players:FindFirstChild(name) (name being the player.Name that you sent from the client).

Yeah still not working as intended. No output in the console either to determine what the issue could be. Everything seems to be in the correct place as you’ve explained to me, but only the LocalScript is working, so I am stumped at this point.

Rather than using if game.Players:FindFirstChild(targetplayer) then you can simply just use if targetplayer and targetplayer.Parent == game.Players then.

Your if statement never returns true because you are giving it a Player (Instance) when FindFirstChild is looking for Name (String).

Weird since from the images you sent everything should simply work if you just add targetplayer.Name in the :FindFirstChild() in the server script. As I said you should probably try sending target players name to the server and getting the player on the server:

--local
if player then
    event:FireServer(player.Name)
end

--server
local targetplayer = game.Players:FindFirstChild(target) --target being the player.Name argument you sent from the client
if targetplayer then
   --clone the gui
end

This is really simple. Look at this:

Everytime tool.Activated is fired, send mouse.Hit to server via a remote.

On the server check if its a player. If it is, then clone the gui from replicated storage to playerHit.PlayerGui.

Alternatively you could have the gui itself in starterGui but disabled, and instead of having the server clone it to the player you could fire a remote to the player hit and locally enable it.

Here is a mistake I found:

Always use player.PlayerGui, as starter gui contains components that are cloned to the playergui only once.

UPDATE: Tried previous two methods and still nothing from the servers side. However, client shows it’s firing the event to the server with the print statement confirming it. And it seems its only sending the gui to the player with the tool, not the player who was targeted.

Not sure what is wrong still.

LocalScript inside of the tool:

local tool = script.Parent
local gui = game.ReplicatedStorage:WaitForChild("ScreenGui")
local ParanoiaEvent = game.ReplicatedStorage.ParanoiaEvent

tool.Activated:Connect(function()
	local mouse = game.Players.LocalPlayer:GetMouse()
	local target = mouse.Target
	if target and target.Parent:FindFirstChild("Humanoid") then
		local player = game.Players:GetPlayerFromCharacter(target.Parent)
		if player then
			ParanoiaEvent:FireServer(player)
			print("Fired event, giving effect...")
		end
	end
end)

Server script inside of ServerScriptService:

local gui = game.ReplicatedStorage.ScreenGui
local paranoiaEvent = game.ReplicatedStorage.ParanoiaEvent

paranoiaEvent.OnServerEvent:Connect(function(targetplayer)
	if targetplayer and targetplayer.Parent == game.Players then
		local newgui = gui:Clone()
		newgui.Parent = targetplayer.PlayerGui
		print("Effect given")
	end
end)

First argument of OnServerEvent is the player who fired the event so you need to add player before targetplayer like this:

paranoiaEvent.OnServerEvent:Connect(function(player,targetplayer)
	--do stuff
end)