UserInputService with tools firing events for everyone

  1. What do you want to achieve? Keep it simple and clear!
    I want to use UserInputService to switch a “mode” that a tool has.
  2. What is the issue? Include enough details if possible!
    The issue is when I use UserInputService, it effects EVERYONE. This makes it so anyone has the tool gets their mode switched.
  3. What solutions have you thought of so far?
    I’ve tried seeing if the player is holding the tool for the mode switching to happen, seeing if whoever is holding the tool is equal to the local player (which doesn’t matter because it happens for everyone, meaning for every local script running, that local player is the one holding the tool)
local tool = script.Parent
local UserInputService = game:GetService("UserInputService")
local ModeSwitchEvent = game.ReplicatedStorage.ModeSwitch

UserInputService.InputBegan:Connect(function(Input, IsTyping)
	if IsTyping == false then
		if Input.KeyCode == Enum.KeyCode.Q then
			ModeSwitchEvent:FireServer()
			print("Mode Switched!")
		end
	end
end)

If there are any alternatives to UserInputService, please let me know. I don’t want to have to use UI (or at least not JUST UI for this.)

2 Likes

Can you show the part of the script that the remote event is being fired to? UserInputService can only affect the local player so your problem probably lies in the script the remote is being fired to.

3 Likes

I don’t think it is the problem, but here it is:

local tool = script.Parent
local currentmode = script.Parent.Mode
local ModeSwitchEvent = game.ReplicatedStorage.ModeSwitch

ModeSwitchEvent.OnServerEvent:Connect(function()
	if currentmode.Value == "Normal" then
		tool.Name = "Blaster [Shotgun]"
		currentmode.Value = "Shotgun"
		tool.Handle.Color = Color3.fromRGB(218, 133, 65)
		print("Mode Change: Normal to Shotgun")
	elseif currentmode.Value == "Shotgun" then
		tool.Name = "Blaster [Boomerang]"
		currentmode.Value = "Boomerang"
		tool.Handle.Color = Color3.fromRGB(35, 200, 189)
		print("Mode Change: Shotgun to Boomerang")
	elseif currentmode.Value == "Boomerang" then
		tool.Name = "Blaster [Fire]"
		currentmode.Value = "Fire"
		tool.Handle.Color = Color3.fromRGB(255, 90, 14)
		print("Mode Change: Boomerang to Fire")
	elseif currentmode.Value == "Fire" then
		tool.Name = "Blaster [Normal]"
		currentmode.Value = "Normal"
		tool.Handle.Color = Color3.fromRGB(52, 142, 64)
		print("Mode Change: Fire to Normal")
	end
end)

And here is what the path looks like:

image

You could try creating a unique remote event for each tool and parenting it to the tool, then you can fire it from the local script.

1 Like

I think if I did then any press from any player would get EVERYONE’s remote event. Either way, the main problem is the fact that UserInputService affects every local script and I either need a way to make that not the case, or to tell which player caused the InputBegan event to fire.

When you fire the remote event, all of the other server events would be listening for the signal, that’s probably why it’s changing the tool for other players. You can also make a single script in ServerScriptService and define tool each time the event is fired, then you can achieve the same thing.

The reason this is happening is because every script is listening for that one singular remote event.
There are two solutions: Make an individual remote for each event, or add these lines of code…

ModeSwitchEvent.OnServerEvent:Connect(function(player) --"player" argument is passed (player = player who fired the event)
	local toolowner = game.Players:GetPlayerFromCharacter(script.Parent.Parent) --This should return the player of the person holding the tool.
	if player ~= toolowner then return end --Check if toolowner fired event

These lines check if the RemoteEvent was fired from the toolowner.

This is a bit unrelated to the question, but I feel like I can help with your code a bit. To me, it looks a bit messy.

local tool = script.Parent
local currentmode = script.Parent.Mode
local ModeSwitchEvent = game.ReplicatedStorage.ModeSwitch

--Add a values table so values can be easily accessed.
-- example: Values[1].Name would be "Blaster [Shotgun]"
-- : Values[2].Display would be "Boomerang"
Values = {
	{
		Name = "Blaster [Shotgun]",
		Display = "Shotgun",
		Color = Color3.fromRGB(218, 133, 65)
	},
	{
		Name = "Blaster [Boomerang]",
		Display = "Boomerang",
		Color = Color3.fromRGB(35, 200, 189)
	},
	{
		Name = "Blaster [Fire]",
		Display = "Fire",
		Color = Color3.fromRGB(255, 90, 14)
	},
	{
		Name = "Blaster [Normal]",
		Display = "Normal",
		Color = Color3.fromRGB(52, 142, 64)
	}
}

previousMode = 1
currentMode = 1

ModeSwitchEvent.OnServerEvent:Connect(function(player) --"player" argument is passed (player = player who fired the event)
	local toolowner = game.Players:GetPlayerFromCharacter(script.Parent.Parent) --This should return the player of the person holding the tool.
	if player ~= toolowner then return end --Check if toolowner fired event
	
	previousMode = currentMode --Get previous mode so you can print "Mode Change: PreviousMode to Mode"
	currentMode = (currentMode % #Values) + 1 --#Values should equal 4, the amount of values
	--The modulo operator '%' makes sure it says within the range of 4
	
	--Wrapped in a pcall incase invalid string is given (exploiters might put random stuff like sdakfjhsldkjfhasdf)
	pcall(function()
		local currentModeName = Values[previousMode].Display
		local currentModeDisplay = Values[currentMode].Display
		local previousModeDisplay = Values[previousMode].Display
		local currentModeColor = Values[currentMode].Color
		
		tool.Name = currentModeName
		currentmode.Value = currentModeDisplay
		tool.Handle.Color = currentModeColor
		
		print("Mode Change: "..Values[previousMode].Display.." to "..previousModeDisplay)
		--[[
			Basically this is concatenating these strings
			Mode Change + Display name of Previous Value + to + Display name of this value
		]]
	end)
end)

Also, please tell me if there are any errors in my code because I wrote it in a bit of a rush

2 Likes

Sorry had to sleep lol, will test that out. Also thank you for the clean code lol I kinda purposefully avoided using things like that but I knew I would have to use things like that eventually, thank you though, will use!

Alright I got the code to work. There were a few issues but that was mainly because of the way I previously had modes change. Here is the new code if you want to compare:

local tool = script.Parent
local currentmode = script.Parent.Mode
local ModeSwitchEvent = game.ReplicatedStorage.ModeSwitch

--Add a values table so values can be easily accessed.
-- example: Values[1].Name would be "Blaster [Shotgun]"
-- : Values[2].Display would be "Boomerang"
Values = {
	{
		Name = "Blaster [Normal]",
		Display = "Normal",
		Color = Color3.fromRGB(52, 142, 64)
	},
	{
		Name = "Blaster [Shotgun]",
		Display = "Shotgun",
		Color = Color3.fromRGB(218, 133, 65)
		
	},
	{
		Name = "Blaster [Boomerang]",
		Display = "Boomerang",
		Color = Color3.fromRGB(35, 200, 189)
		
	},
	{
		Name = "Blaster [Fire]",
		Display = "Fire",
		Color = Color3.fromRGB(255, 90, 14)
	}
}

previousMode = 4
currentMode = 1

ModeSwitchEvent.OnServerEvent:Connect(function(player) --"player" argument is passed (player = player who fired the event)
	local toolowner = game.Players:GetPlayerFromCharacter(script.Parent.Parent) --This should return the player of the person holding the tool.
	if player ~= toolowner then return end --Check if toolowner fired event

	previousMode = currentMode --Get previous mode so you can print "Mode Change: PreviousMode to Mode"
	currentMode = (currentMode % #Values) + 1 --#Values should equal 4, the amount of values
	print(currentMode)
	--The modulo operator '%' makes sure it says within the range of 4

	--Wrapped in a pcall incase invalid string is given (exploiters might put random stuff like sdakfjhsldkjfhasdf)
	pcall(function()
		local currentModeName = Values[currentMode].Name
		local currentModeDisplay = Values[currentMode].Display
		local previousModeDisplay = Values[previousMode].Display
		local currentModeColor = Values[currentMode].Color

		tool.Name = currentModeName
		currentmode.Value = currentModeDisplay
		tool.Handle.Color = currentModeColor

		print("Mode Change: "..Values[previousMode].Display.." to "..currentModeDisplay)
		--[[
			Basically this is concatenating these strings
			Mode Change + Display name of Previous Value + to + Display name of this value
		]]
	end)
end)

I’m worried that the code

ModeSwitchEvent.OnServerEvent:Connect(function(player) --"player" argument is passed (player = player who fired the event)

won’t matter because the onserverevent is being fired from every local script, but I’m going to need to find a friend to test it. But thank you very much, this code is MUCH cleaner than it was before, thank you!

1 Like

Seems to work fine, was even able to add mobile support! Thank you!

1 Like

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