Why does my server script return an error saying attempt to index nil with 'Hit' when using player:GetMouse()

I’m making a gun script but it can’t get the hit function from the GetMouse() function, I’ve started the game and opened the script and tested if it allowed the GetMouse() function and it did yet it returned this:

17:23:18.011  Mouse object is nil  -  Server - Server:32
  17:23:18.011  Players.killersuperlegend.Backpack.Gun.Handle.Server:35: attempt to index nil with 'Hit'  -  Server - Server:35
  17:23:18.011  Stack Begin  -  Studio
  17:23:18.011  Script 'Players.killersuperlegend.Backpack.Gun.Handle.Server', Line 35  -  Studio - Server:35
  17:23:18.011  Stack End  -  Studio

When I click with the mouse.

Here’s the code:

local Tool = script.Parent.Parent
local Sounds = script.Parent.Sounds

Tool.Equipped:Connect(function()
	Sounds.Equip:Play()
end)

Tool.Unequipped:Connect(function()
	Sounds.Unequip:Play()
end)

Tool.Activated:Connect(function()
	Sounds.Activated:Play()
	script.Parent.Shot.GunShotLight.Enabled = true
	script.Parent.Shot.Transparency = 0
	script.Parent.Shot.Smoke1.Enabled = true
	script.Parent.Shot.Smoke2.Enabled = true
	script.Parent.Dispenser.s1.Enabled = true
	script.Parent.Dispenser.s2.Enabled = true
	script.Parent.Dispenser.s3.Enabled = true
	script.Parent.Dispenser.s4.Enabled = true
	script.Parent.Dispenser.s5.Enabled = true
	script.Parent.Dispenser.Decal1.Transparency = 0
	script.Parent.Dispenser.Decal2.Transparency = 0
	local player = game.Players:GetPlayerFromCharacter(script.Parent.Parent.Parent)
	local mouse = player:GetMouse()
	if mouse then
		print("Mouse object is valid")
		print(mouse.Hit)
	else
		print("Mouse object is nil")
	end

	local ray = Ray.new(script.Parent.Position, (mouse.Hit - script.Parent.Position).unit * 100)
	local part, hitPos = workspace:FindPartOnRay(ray, player.Character)

	if part and part.Parent and part.Parent:FindFirstChild("Humanoid") and part.Parent ~= player.Character then
		local targetHumanoid = part.Parent:FindFirstChild("Humanoid")
		if targetHumanoid.Parent ~= script.parent.parent.parent then -- blacklist the player holding the gun
			targetHumanoid.Health = targetHumanoid.Health - 30
		end
	end

	wait(0.01)
	script.Parent.Shot.Transparency = 1
	script.Parent.Shot.GunShotLight.Enabled = false
	script.Parent.Shot.Smoke1.Enabled = false
	script.Parent.Shot.Smoke2.Enabled = false
	script.Parent.Dispenser.s1.Enabled = false
	script.Parent.Dispenser.s2.Enabled = false
	script.Parent.Dispenser.s3.Enabled = false
	script.Parent.Dispenser.s4.Enabled = false
	script.Parent.Dispenser.s5.Enabled = false
	script.Parent.Dispenser.Decal1.Transparency = 1
	script.Parent.Dispenser.Decal2.Transparency = 1
end)

I’ve tried using ChatGPT to debug the code but it doesn’t work and I don’t know what to search for to find the solution.

What is the problem with the code?

If its in a server script, It wont work, Server scripts cannot get the mouse, You will have to fire a remote event instead (i believe)

How?
Btw, I used GetPlayerFromCharacter so shouldn’t that work?

The problem is not the way you are getting the player, The mouse cannot be detected at all via server, so you can make a local script inside the tool that fires a remote event in the tool when you activate it (on the local script) and then use the OnServerEvent function in the server script to detect it, make sure you pass in the mouse.hit.p as a parameter, And make sure the OnServerEvent function has “plr” as its first parameter (you dont have to pass in the plr in the local script) because thats how the remote events work (mouse.hit.p is a vector3 i believe)

2 Likes

As mentioned earlier, you cannot (and probably will never be able to) access a player’s mouse through the server. You must retrieve the mouse locally, as it is not automatically replicated from the client to the server. But there’s a workaround on this fact, you may create custom server controls for it.

For example:

-- LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Client = Players.LocalPlayer
local RemoteFunction = ReplicatedStorage.GetMouseHit

local Mouse = Client:GetMouse()

function RemoteFunction.OnClientInvoke()
    return Mouse.Hit
end

However, you must be careful when using this solution. If the player leaves while calling it, or if something goes wrong locally, an error will be sent to the server. Additionally, the client will always be able to manipulate the result returned from this function, so you should use it wisely.

Example of use in server:

-- ServerScript
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetMouseHit = ReplicatedStorage.GetMouseHit

local function PlayerAdded(Player: Player)
    local MouseHit
    
    pcall(function()
        MouseHit = GetMouseHit
:InvokeClient(Player)
    end)
    
    if MouseHit then
        print(`{Player}s mouse hit: {MouseHit}`)
    else
        warn(`Failed getting {Player}s mouse hit`) 
    end
end

Players.PlayerAdded:Connect(PlayerAdded)

More informations about remote instances: Remote Events and Callbacks | Documentation - Roblox Creator Hub

1 Like