RaycastResult.Normal returning nil value

Background

I am trying to make a raycast gun, and when attempting to use RaycastResult.Normal to make a bullet hole function, I always seem to get an error and I am unsure on how I can fix it.

image

Scripts

LocalScript:

local tool = script.Parent
local remote = tool:WaitForChild("ShootEvent")

local Players = game:GetService("Players")
local client = Players.LocalPlayer
local cursor = client:GetMouse() 

tool.Activated:Connect(function()
	remote:FireServer(cursor.Hit.Position)
end)

ServerScript:

local tool = script.Parent
local shoot_part = tool:WaitForChild("Shoot")
local remote = tool:WaitForChild("ShootEvent")

local ServerStorage = game:GetService("ServerStorage")

remote.OnServerEvent:Connect(function(player, position)
	if player == game.Players:GetPlayerFromCharacter(script.Parent.Parent) then
		local origin = shoot_part.Position
		local direction = (position - origin).Unit * 300
		
		local params = RaycastParams.new()
		params.FilterDescendantsInstances = {player.Character}
		params.FilterType = Enum.RaycastFilterType.Whitelist
		
		local result = workspace:Raycast(origin, direction, params)
		
		local intersection = result and result.Position or origin + direction	
		local distance = (origin - intersection).Magnitude
	
		local bullet_clone = ServerStorage.Bullet:Clone()
		bullet_clone.Size = Vector3.new(0.1, 0.1, distance)
		bullet_clone.CFrame = CFrame.new(origin, intersection)*CFrame.new(0, 0, - distance / 2)
		bullet_clone.Parent = workspace.BulletFolder
		
		local normal = result.Normal -- Error line
			
		local hole_clone = ServerStorage.Hole:Clone()
		hole_clone.Position = position
		hole_clone.CFrame = CFrame.new(position, position + normal) -- Variable used
		hole_clone.Parent = workspace.BulletFolder
		
		if result then
			local part = result.Instance
			local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")
			
			if humanoid then
				humanoid:TakeDamage(10)
			end
		end
		
		game.TweenService:Create(bullet_clone,TweenInfo.new(0.2,Enum.EasingStyle.Quad ,Enum.EasingDirection.Out), {Transparency = 1}):Play()
		wait(0.2)
		bullet_clone:Destroy()
	end
end)

Images

Image of tool:
image
Image of ServerStorage:
image

Any help would be appreciated, thank you!

Credit to @incapaz creating the helpful tutorial, you can view it here: How to make a raycasting gun

You should do the normal variable inside the if result.

if result then
   local normal = result.Normal			
   local hole_clone = ServerStorage.Hole:Clone()
   hole_clone.Position = position
   hole_clone.CFrame = CFrame.new(position, position + normal) -- Variable used
   hole_clone.Parent = workspace.BulletFolder
   -- Rest of the code you put on the if result
end
2 Likes

I tried this before when looking at the DeveloperHub, but found that the code didn’t even run. It seemed like the if result then was returning false, which I wasn’t sure why.

Edit: I just put a print(1) in the if statement to check if it was running, and it wasn’t. Odd.

That means WorldRoot:Raycast returned nil because the ray cast didn’t hit anything. It only returns a RaycastResult if something was hit.

also thanks for using my tutorial :slight_smile:

2 Likes

Oh wait just noticed the error.

It should be Blacklist instead.

1 Like

The innisial part of the script above the if statement works, and the bullet part does get cloned to workspace.

And yes haha, very cool tutorial, thank you!

2 Likes

Thank you! I’ll try this out and let you know if it fixes it!

Edit: Woo hoo! it’s fixed, thank you!

1 Like