You should check out the FastCast module.
How I use it is like this:
Remote.OnServerEvent:Connect(function(Player: Player, Position: Vector3, OriginPosition: Vector3, IsShotgun: boolean, FireSound: Sound)
if Tool.Parent ~= Player.Character or Player.Character:FindFirstChildOfClass("ForceField") then return end
-- For gun shoot effect
--[[for _, Object in Tool.Handle.Barrel:GetChildren() do
if Object:IsA("ParticleEmitter") then
Object:Emit()
end
if Object:IsA("PointLight") then
Object.Enabled = true
task.delay(0.6, function()
Object.Enabled = false
end)
end
end]]
local Direction = (Position - OriginPosition).Unit
local Cast = BulletCaster:Fire(OriginPosition, Direction, GunData.Velocity/10, BulletBehavior)
Cast.RayInfo.CosmeticBulletObject:SetAttribute("Player", Player.Name)
FireSound:Play()
end)
As for the event being fired this is what I do:
self.ShootEvent:FireServer(Mouse.Hit.Position, self.Tool.Barrel.Position, self.IsShotgun, self.Fire)
You can handle the ray hitting using FastCast’s RayHit event.