The position of the bullet hole is not correct

Hello im have problem with bullet hole.
The fact is that when I shoot, the hole appears at the mouse position, and not where Ray hit. Im don’t know how to fix this.
Server script:

tool.Fire.OnServerEvent:Connect(function(player, mouseHit, rate)
	if script.Parent.CanFire.Value == false then
		script.Parent.CanFire.Value = true
		Ammo.Value = Ammo.Value - 1
		local fires = tool.Handle.Fire:Clone()
		fires.Parent = tool.Handle
		local ray =, (mouseHit.p - tool.Handle.GunFirePoint.WorldCFrame.p).unit * 300)
		local hit, position, normal = game.Workspace:FindPartOnRay(ray, player.Character, false, true)
		local distance = (position - tool.Handle.GunFirePoint.WorldCFrame.p).magnitude
		local part ="Part")
		part.Name = "Bullet"
		part.Anchored = true
		part.CanCollide = false
		part.Material = "Neon"
		part.BrickColor ="Gold")
		part.Size =, 0.1, distance)
		part.CFrame =, tool.Handle.GunFirePoint.WorldCFrame.p) *, 0, - distance / 2)
		part.Parent = workspace
		if hit and hit.Parent ~= workspace.BulletHoles then
			if hit.Parent and hit.Parent ~= workspace.BulletHoles then
				local hole = game.ReplicatedStorage.Metal:Clone()
				hole.Name = "Bullet Hole"
				hole.Parent = workspace.BulletHoles
				hole.Position = mouseHit.p
				hole.CFrame =, hole.Position + normal)

				local weld ="Weld")
				weld.Part0, weld.Part1 = hit,hole
				weld.C0 = hit.CFrame:Inverse()
				weld.C1 = hole.CFrame:Inverse()
				weld.Parent = hole
				game:GetService("Debris"):AddItem(hole, 8)
				if hit.Parent:FindFirstChild("Humanoid") and hit.Name == "Head"  then
				if hit.Parent:FindFirstChild("Humanoid") then
				elseif hit.Parent:FindFirstChild("Humanoid") and hit.Name == "Left Leg" or hit.Name == "Right Leg" then
		game:GetService("Debris"):AddItem(part, 0.03)
	script.Parent.CanFire.Value = false

(Please make a script and explain the lines to me. I don’t know much programming)

The position and rotation of the bullet hole is defined as:

Which is unfortunate cause you are not using your raycast position from:

I am not sure if the normal is used properly, but the position should be the hit of your raycast. Also, there is no need to set hole.Position if you are setting hole.CFrame.

I would probably define ‘hole’ as:

// Your old code
local hole = game.ReplicatedStorage.Metal:Clone()
hole.Name = "Bullet Hole"
hole.Parent = workspace.BulletHoles
// New CFrame
hole.CFrame =, position + normal)

Beware that Workspace:FindPartOnRay is deprecated and Workspace:Raycast is recommended.


Thanks for the explanation! I’ll try it now.

You did use the raycast normal properly (see CFrame from normal).

1 Like

Thanks! Everything works perfectly! Now I will know how to correctly define a CFrame.
Thanks to people like you, I will learn Luau better.

1 Like