Bullet hole decal help for a physical bullet

(Apologies in advance if I’m not explaining in a clear way, if any of this confuses you, and the length of this.)

Explanation of what I’m trying to do.
I’m attempting to make a gun that shoots physical bullets rather than a ray-casted beam.
The bullet is stored in ReplicatedStorage and once the gun detects a click the bullet is cloned and brought to the position and orientation of the barrel
(the bullet is also put into a folder in workspace titled ‘Bullets’)
and a VectorForce pushes the bullet forward.
I’m trying to have once the bullet hits an object it puts a decal bullet hole where it hit.

Main Issue
The issue is I’m trying to create a raytracing beam from the bullet to where it hits.
I’m aware of what the issue is, which I’ll mention after the script, but I just need suggestions of what would work in my case.

I’m not trying to have the bullet hole decal to be put where your mouse positions are where I’m aiming since where the bullet shoots from isn’t related to your mouse position but the barrel position and orientation.

Script
This is the script.

local Bullet = script.Parent

local Force = Bullet.VectorForce

script.Parent.Touched:Connect(function(hit)
	
	if hit.Name == "Bullet" or hit.Name == "HitBox" then
		
	elseif hit.Name == "BulletStoppingWall" then
			
		print("Hit name is "..hit.Name)
		print("Parent of hit is "..hit.Parent.Name)
		print("Parent of the parent of hit is "..hit.Parent.Parent.Name)

		pcall(function()
			
			--Ignore everything this pcall function
			--I'm most likely just going to delete the bullet after the decal is added

			Force.Enabled = false

			Force:Destroy()

			Bullet.Anchored = true
			
		end)
			
		local FromP = Bullet.Position
		local ToP = hit.Position
			
		local RayCast = Ray.new(FromP, (ToP-FromP).Unit*100)
		local PartForRay, Position, Normal = game.Workspace:FindPartOnRay(RayCast, Bullet, false, true)
			
		if PartForRay then
				
			--damage
				
		end
			
		local Laser = Instance.new("Part")
			
		Laser.Parent = game.Workspace.BulletsReRouteToWorkspace.BulletHoles
		Laser.CanCollide = false
		Laser.Anchored = true
		
		local Dist = (ToP-FromP).Magnitude
			
		Laser.CFrame = CFrame.new(FromP, Position)*CFrame.new(0,0, -Dist/2)
		Laser.Size = Vector3.new(0.1, 0.1, Dist)
			
		game.Debris:AddItem(Laser, 0.2)
			
		local BulletHole = game.ReplicatedStorage.Bullets.BulletHoles.P90BulletHole:Clone()
			
		BulletHole.Parent = game.Workspace.BulletsReRouteToWorkspace.BulletHoles
		BulletHole.Position = ToP
		BulletHole.CFrame = CFrame.new(FromP, Position)*CFrame.new(0, 0, -Dist)
			
		game.Debris:AddItem(BulletHole, 15)

	else		
		
	end
	
end)

(The elseif hit.Name == "BulletStoppingWall" then is just there so I can test on a certain wall.)

The issue with this script is the position of where the decal is being sent.
It’s being sent to the ToP (hit) position, which causes the decal to be put into the very center of the block it’s hitting.

I would just like to know if there’s a possible solution to create bullet holes that fit my circumstance that don’t require mouse tracking.

If there’s none, and if I’m required to have to use the mouse position, then I know I can probably just have the gun point where your mouse points and have a shift lock or first-person lock when you equip the gun.

But if there is, I would really appreciate it.

Smaller Issue.
Another small issue to, which doesn’t really matter if I get rid of the bullet after the decal is put on the wall is the VelocityForce.
For some reason I’ve tested the shooting too and the bullet detected a hit way before it’s hit anything
(I tested with the pcall function and had the bullet just anchor where it hit).
When the bullet itself isn’t in Workspace for testing and brought into Workspace from ReplicatedStorage via a script this bug usually occurs.
But, when it’s just in Workspace when I’m testing the bullet, it works almost perfectly and stops inside the block.
If anyone knows why this is, it’d be much appreciated if you could tell me why and some solutions.

Any help or suggestions is appreciated.

1 Like

If you can get the position of where the bullet hit, and the Instance that the bullet hit, you can create a raycast from either the barrel of the gun or the camera, to the bullets end position, with the part the bullet hit being on the raycast whitelist.

local RayParams= RaycastParams.new()
RayParams.FilterDescendantsInstances = {'The Part The Bullet Hit'}
RayParams.FilterType = Enum.RaycastFilterType.Whitelist
-- Making the FilterType 'Whitelist' makes it that only parts in the table will collide with the ray.
local RayOrigin = Camera.CFrame.Position
local RayDirection = (Camera.CFrame.Position - 'Position Of Where The Bullet Hit').Unit * -500
-- 500 is the max length of the raycast, you can change it if you want.
-- For guns, i would recommend to use around 10000 or 5000 for the rays length.

local Result = workspace:Raycast(RayOrigin, RayDirection, RayParams)

Then, after raycasting, you would want to then get the rays normal, and translate that to a Vector3, then position and rotate your bullet hole decal, and youre done!

if Result and Result.Normal and Result.Position then
	local BulletHole = 'Directory to your bullet hold part, and make sure the decal is on the front!'
	BulletHole.CFrame = CFrame.new(Result.Position, Result.Position + Result.Normal)
end

Edit:
I’m not sure if this is what youre looking for, but from what i read, this might help.
All it really does is positions and rotates a part to be flat on a surface.

1 Like

Sorry for the late reply, but I’ll try this out when I’m free and I’ll get back to you.

This works almost perfectly. Sometimes the bullet hole doesn’t appear, but I’m pretty sure I can iron the bugs out and make sure it works perfectly so this doesn’t happen. Thank you though, I really appreciate this, it works exactly how I wanted the gun to work.