How to create bullet tracers!

,

Intro part (you can skip it if you want nothing important, but i recommend you read it)

Hello Everyone, I’ve been making an fps game for a while now and when it was time to add gun tracers (such as the ones in Phantom Forces or the game Blood Engine) i really came to a struggle. I tried using physical parts with velocity and trails, but this didn’t work too well (very bad method btw - saying this from experience, only use it for slow projectiles).
I tried using other methods but no success, I don’t see that many people talking about this, so i decided to just make a tutorial cuz why not lol.

(We will be using beams btw)

Anyway lets begin with our tutorial, I will try to make it as simple and as easy to understand as possible, but remember some scripting knowledge is needed so keep that in mind.

Step 1!!!

Set up the beam

  1. Grab two parts and set their collision to false, transparency to 1 and etc.

  1. Add attachemnts to both parts and a beam, then name the first part “Part1” and the second one(the end destination one) “Part2”

  1. Ok now we need to customize the beam, i wont go too much in detail since it will be a waste of time, but i will share my properties
    image
    image

Tadaaa

This should be your final result or at least something similar to it

Step 2

Set up the code

Now we will be doing this ON THE SERVER SIDE

  1. Set up your working space, organize your tracers like this so
    image
    (highlighted part) (Att1 and Att0 are basically Part1 and Part2)

Now I suppose you already have a gun system in place, I will show you pieces of code used in my own game for the tracers. The following code can be used by anyone. Anyway it will consist of a function that can be called to summon a tracer

local function Tracer(a: Attachment, HitPos : Vector3, dist: Number)
	task.spawn(function()
		--"a" is our starting attachment AKA - the muzzle of the gun
		--"HitPos" is our end position. Assuming raycasting is used, this would result in it being the position of where the shot hits
		--"dist"  is the distance between the muzzle/player and the HitPos, in this instance we are precalculating it OUTSIDE the modular function
		local attachment0 = game.ReplicatedStorage.GunResources.Tracers.Part1.Attachment:Clone()
		attachment0.Parent = a
		local attachment1 = game.ReplicatedStorage.GunResources.Tracers.Part2:Clone()
		attachment1.Parent = workspace.Terrain
		local tracer = game.ReplicatedStorage.GunResources.Tracers.Att0.Beam:Clone()
		tracer.Parent = a


		attachment1.Position = HitPos
		tracer.Attachment0 = a
		tracer.Attachment1 = attachment1.Attachment
		tracer.CurveSize1 = (dist / 30) + (dist / 30) 
		tracer.TextureLength = dist / 3
		task.wait(.05)

		attachment0:Destroy()
		attachment1:Destroy()
		tracer:Destroy()

	end)
end

Example Usage :

local dist = (ray.Position - gun.Muzzle.Position).Magnitude
local a = gun.Muzzle.Attachment -- The start point of the tracer - where the tracer's path starts

Tracer(a, ray.Position, dist)

Now since our code uses beams, it should work with viewmodels too (if the physical gun is reattached to the viewmodel, instead of the viewmodel being a separate rig)

THIS SHOULD NOW BE OUR FINAL RESULT (Video taken from my game still in development so it don’t judge) (These are not the best tracers but as i said you can customize the beam and if you are a scripter you can change my code too, but i believe this is a good base)

Sorry for the very poor video quality and fps but trust me in game it looks A LOOOT better

FIRST PERSON

Third Person

NOTE : I am not the best scripter, i can argue that i am a pretty good one but no the best, so if any bugs are found, please report them in the replies and i will answer every one of you with hopefully a solution

Hope you found this helpful and i’d be cool if you drop me a follow @RobloxerAndany (aka FangOne2) :smiley:

30 Likes

really cool! thanks for this info, ive been wondering how to make tracers for a while. i was previously trying to do it with a mesh part…

Hello! I would like to know how you came up with the tracer’s CurveSize1 and TextureLength formulas.

Honestly a lot of tests until i got a decent version, i also used visual representations, it can help too

1 Like

Oh thank you! I’m guessing that these simple formulas are used for the tracer to only fire (or appear) the texture once, not twice or thrice. Wonderful resource!

hi,

  1. how do you know the curve size is the same of the projectile velocity and game setting if customized, gravity.

  2. and I sorta looked at the code, does the tracer only go so far, and the projectile could or does go further

Thanks

well i COULD include gravity in the equation but i decided not to, again this is a very basic version and its fully customizable, Also i think you misunderstood me. My system uses raycasting - INSTANT hit detection so velocity is just not needed

1 Like

how do I… make it look the same as yours? (using the same func as urs btw)

Alr i suppose the muzzle attachment - where the tracer comes from is positioned incorrectly

I found a easier way to have similar bullet tracers by using trails instead of beams, which look like beams if the part is moving fast.

Which does make is easier to add bullet drop/gravity/wind since its a part and not two beam attachments, but it makes it impossible (I think?) to add smear frames or use beizer to make it actually look like PF.

So thats a tradeoff.

Nvm came back later and figured it out, basically in the tutorial i said that it can work for viewmodels IF the actual third person physical gun is reattached to the viewmodel once u go in first person, in your case, you have to cast a second tracer for the client and hide the server one(only on the client)

i just used trails + fast cast so i dont need to do allat math for bullet drop

though it reduces the modifiability so i cant add bezier curves for smear frames anymore for maximum PF-level quality

1 Like