How to get player that owns a tool

So, I’m trying to make a sort of “Global Raycasting Function” that I can call from wherever and I’m testing it by having it change something in the player’s UI. Problem is that I’m struggling to get the player that’s calling the raycast since it always throws nil

For an additional bit of context, im using the default Roblox Tool just as a means to test the function. What I’m trying to do is to get the player object from the player that owns the tool, but it isn’t.

Here’s the code for both the gun tool in question and the raycasting function

script.Parent.Activated:Connect(function()
local gunData = require(script.Parent.gunInfo)
local GFunc = require(game:GetService(“ServerStorage”).globalFunctions)
local plr = game:GetService(“Players”)
print(script.Parent.Parent.Parent)
GFunc.fireWeapon(gunData,script.Parent.Parent.Parent)
local event = game:GetService(“ReplicatedStorage”):WaitForChild(“testEvent”)
local function receive(player,result)
game.Players.LocalPlayer.PlayerGui.hitUI.result.Text = result
end
event.OnClientEvent:Connect(receive)
end)

local module = {}

function module.fireWeapon(weapon,player)
–Setting up position and orientation of the
local origin = weapon.Flame.Position
local direction = Vector3.new(weapon.Flame.Orientation.X,weapon.Flame.Orientation.Y - 90,weapon.Flame.Orientation.Z)
–Casting the actual ray
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {weapon.caster}
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
local rayResult = workspace:Raycast(origin,direction,rayParams)
print(“Success!”)
local event = game:GetService(“ReplicatedStorage”):WaitForChild(“testEvent”)
–Hit detection
if rayResult then
local result = “Hit”
event:FireClient(player,result)
else
local result = “Miss”
event:FireClient(player,result)
end
end

return module

I’m sorry if the format of the code isn’t the best. I’m very new to posting on the forums

Do you know which line is retuning nil?

I would try something like this:

local Players = game:GetService("Players")

local tool = script.Parent

local function getPlayer()
	local classes = {
		["Model"] = function(parent)
			if parent:FindFirstChildWhichIsA("Humanoid") then
				-- Parent is a character
				return Players:GetPlayerFromCharacter(parent)
			end
		end;
		["Backpack"] = function(parent)
			return parent.Parent --The parent of a backpack is always a player
		end
	}
	
	local parent = tool.Parent
	local func = classes[parent.ClassName]
	if func ~= nil then
		-- The parent of the tool could possibly be a player
		return func(parent)
	end
end

I think the issue here is that you’re trying to access the ServerStorage from a local script

script.Parent.Activated:Connect(function()
    local gunData = require(script.Parent.gunInfo)
    local GFunc = require(game:GetService("ServerStorage").globalFunctions) -- error here
    local plr = game:GetService("Players")

ServerStorage | Documentation - Roblox Creator Hub
Objects descending from ServerStorage will not replicate to the client and will not be accessible from LocalScripts.

You should instead be firing a remote to do the raycasting instead, all the raycasting has to be done on the server. This is because the globalFunctions module also has usage of FireClient(), which cannot be used on the client (only on the server).

So, for this all I would need to do would be to fire the remote on the server and do the require for the function in a server script instead of a local?

Yup. Do FireServer() on the client, firing a remote that requires the module and calls the function.

idk if this works but

local Players = game:GetService("Players")

local function checkBackpack()
	return script:FindFirstAncestorWhichIsA("Player")
end

local function checkCharacter()
	return Players:GetPlayerFromCharacter(script:FindFirstAncestorWhichIsA("Model"))
end

local function getPlayer()
	return checkBackpack() or checkCharacter()
end