Raycast for hammer tool not working

For context, i was trying to make a hammer that could spawn props if you click somewhere on a 15 stud distance. however when i tried running the code it said that

Players.unturnedfan505.Backpack.Barricade.Raycast:7: attempt to index nil with 'Character'

I have tried multiple ways to reference the character variable and none of them worked, im not sure if its because of how the script is structured.

Heres the code:

local tool = script.Parent
local use = tool:WaitForChild("Sounds").Use

local uis = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

--settings

local cooldown = 5
local distance = 15


local function MouseRaycast()
	
	local mousepos = uis:GetMouseLocation()
	local mouseray = camera:ViewportPointToRay(mousepos.X, mousepos.Y)
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {}
	params.FilterType = Enum.RaycastFilterType.Exclude
	local result = workspace:Raycast(mouseray.Origin, mouseray.Direction * distance)
	
	return result
	
end

tool.Activated:Connect(function() 
	
	local part = Instance.new("Part")
	part.Parent = workspace
	part.Position = MouseRaycast().Position
	part.Anchored = true
	part.CanCollide = false
	part.Size = Vector3.new(0.1, 0.1, 0.1)
	part.Name = "Raycast"
	part.BrickColor = BrickColor.new("Really red")
	part.Material = Enum.Material.Neon
	part.Shape = Enum.PartType.Ball
	
	use:Play()
	
	print("placed raycast part sucessfully")
	
	task.wait(5)
	part:Destroy()
	
end)


1 Like

Is this a server or a LocalScript?

It is a server script located inside the tool.

I think I know the issue. The problem is, game.Players.LocalPlayer only works in a LocalScript, which is why it says that the character variable is nil. A workaround to getting the player can be this:

local player = game:GetService("Players").PlayerAdded:Wait()

That fixed the errors, but now it isnt appearing to be doing anything (making the parts in the Activated event).

I’ve tried changing up a few things but it didnt work.

local tool = script.Parent
local use = tool:WaitForChild("Sounds").Use

local uis = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local player = game:GetService("Players").PlayerAdded:Wait()
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

--settings

local cooldown = 5
local distance = 10000


local function MouseRaycast()
	
	local mousepos = uis:GetMouseLocation()
	local mouseray = camera:ViewportPointToRay(mousepos.X, mousepos.Y)
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {character}
	params.FilterType = Enum.RaycastFilterType.Exclude
	local result = workspace:Raycast(mouseray.Origin, mouseray.Direction * distance)
	print("i did it")
	
	return result
	
end

tool.Activated:Connect(function() 
	
	local raycast = MouseRaycast()
	print(raycast.Position)
	
	local part = Instance.new("Part")
	part.Parent = workspace
	part.Position = raycast.Position
	part.Anchored = true
	part.CanCollide = false
	part.Size = Vector3.new(1, 1, 1)
	part.Name = "Raycast"
	part.BrickColor = BrickColor.new("Really red")
	part.Transparency = 0
	part.Material = Enum.Material.Neon
	
	use:Play()
	
	print("placed raycast part sucessfully")
	
	task.wait(5)
	part:Destroy()
	
end)


Do you want the object to also print in the sky to? Sorry for the late reply, I was just busy.

You need to do the mouse calculations in a local script and send that over in a RemoteEvent since a server script can’t use UserInputService.

Probably not, instead if you tried clicking somewhere out of distance or in the sky a “error” sound would play.

How would i send the mouse calculations result? Maybe using the result variable? Im not too knowledgeable of remote events so correct me if im wrong.

Here’s some code that works. Though it only works on the client side, I’ll update you if i get it working on the server side.

local tool = script.Parent
local use = tool:WaitForChild("Sounds").Use

local uis = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

--settings

local distance = 15

local function MouseRaycast()

	local mousepos = uis:GetMouseLocation()
	local mouseray = camera:ViewportPointToRay(mousepos.X, mousepos.Y)
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {character}
	params.FilterType = Enum.RaycastFilterType.Exclude
	local result = workspace:Raycast(mouseray.Origin, mouseray.Direction * distance, params)
	
	print(result)
	
	return result
end

tool.Activated:Connect(function()
	local raycast = MouseRaycast()
	if raycast == nil then return end
	
	local part = Instance.new("Part")
	part.Parent = game.Workspace
	part.Position = raycast.Position
	part.Anchored = true
	part.CanCollide = false
	part.Size = Vector3.new(1, 1, 1)
	part.Name = "Raycast"
	part.BrickColor = BrickColor.new("Really red")
	part.Transparency = 0
	part.Material = Enum.Material.Neon

	use:Play()

	print("placed raycast part sucessfully")

	task.wait(5)

	part:Destroy()
end)