Hello everyone, for a while I felt my guns were a little boring, so I decided to spice them up with some bullet tracers. While I found a way to handle them, I noticed they weren’t lining up with where the bullet actually landed, getting closer and closer the further you went. As seen here.
The problem was that the origin of the bullet was the shooter’s head, to prevent players from sticking the gun barrel out of a corner and being unhittable. Every gun has an attachment which acts as the fire point for the tracers. Nothing I could do resulted in what I wanted. Code below.
local tweenService = game:GetService("TweenService")
local module = {}
module.Ballistics = {}
local ballistics = module.Ballistics
ballistics.MakeTracer = function(bulletPart, origin)
bulletPart.Parent = workspace.Ignore
bulletPart.CFrame = CFrame.new(bulletPart.Position, origin.WorldPosition)
local dist = (origin.WorldPosition - bulletPart.Position).Magnitude
local goals = {}
goals.Length = 0
goals.Thickness = 0
local LHA = Instance.new("LineHandleAdornment")
LHA.Thickness = 5
LHA.Length = dist
LHA.Adornee = bulletPart
LHA.Parent = bulletPart
LHA.Color3 = Color3.fromRGB(218, 133, 65)
local tween = tweenService:Create(LHA, TweenInfo.new(1), goals)
wait(0.1)
tween:Play()
tween.Completed:Connect(function()
bulletPart:Destroy()
end)
end
function ballistics:MakeBullet(sourcePos, toPos, maxDist)
local bullet = Instance.new("Part")
bullet.Parent = workspace.Ignore
bullet.Transparency = 1
bullet.CanCollide = false
bullet.Size = Vector3.new(0.25, 0.25, 1.25)
bullet.Anchored = true
bullet.CFrame = CFrame.new(sourcePos, toPos)
bullet.Position = bullet.Position + bullet.CFrame.LookVector * maxDist
toPos = bullet.CFrame
return toPos, bullet
end
ballistics.Fire = function(user, config, mousePos, gun)
--user is the player's character
--config is the module that holds all the gun's stats. Think damage and/or magazine capacity
--mousePos is the player's mouse cframe
--gun is the tool instance
local fromPos = user.Head.Position
local endPoint, bullet = ballistics:MakeBullet(fromPos, mousePos.p, 5000)
coroutine.resume(coroutine.create(ballistics.MakeTracer), bullet, gun.weapon_model.Main.FirePoint)
--weapon_model is the Model instance that holds the gun's parts
--Main is the, well, main part of the model
--FirePoint is the attachment where the tracer should originate from
end
return module
The code is a heavily modified snippet of what the module actually is, for simplicity. If I didn’t explain something enough, let me know!