How should i replicate bullets?

Sorry for the vague title, kinda hard to explain in a sentence.
creating guns, and for the bullet creation, im not sure what to do

im lost as of right now, tried doing it in a single script for all bullet replication but this seems very “inefficient” / just doesnt feel right.

with the current method i have it setup something like this
(the code does not work. i didnt go through with the idea.)

Local Script in the tool
repeat task.wait() until game:IsLoaded() and script.Parent:FindFirstChild("Remotes")

-- Services
local Player = game:GetService('Players').LocalPlayer
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Ts = game:GetService("TweenService")
local Debris = game:GetService("Debris")

-- Tool Variables
local Tool = script.Parent
local Mesh = Tool.GlockMesh
local Handle = Tool.Handle
local BulletPoint = Mesh.BulletPoint
local FirePoint = Tool.GlockMesh.BulletPoint

-- Variables
local RemotesFolder = Tool.Remotes
local RSRemotesFolder = game.ReplicatedStorage.Remotes
local ClientBullet = RSRemotesFolder.ClientBullet
local BulletFolder = game.ReplicatedStorage.Bullets
local ShootEvent = RemotesFolder.Shoot
local ReloadEvent = RemotesFolder.Reload
local CheckEvent = RemotesFolder.Check

-- Unassigned Variables
local BulletCoroutine
local RBullet

-- RayCastParams
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist

-- Tool Data --
local IsAutomatic = true
local LastShotTime = os.clock()
local FireRate = 0.1

local IsHeldDown = false
local Distance = 300
local Bullet = game.ReplicatedStorage.Bullets.NormalBullet
--           --

-- Functions --
local function FireClientBullet(MousePosition)
	local Dbp1 = workspace.DebugPart1
	local Dbp2 = workspace.DebugPart2
	local Dbp3 = workspace.DebugPart3
	local Dbp4 = workspace.DebugPart4
	local Dbp5 = workspace.DebugPart5
	
	-- 
	local MouseDirection = MousePosition.Direction * 10000 -- N
	local MouseRay = workspace:Raycast(MousePosition.Origin, MouseDirection, Params) -- Y
	
	local MouseRayPosition = if MouseRay then MouseRay.Position else (MousePosition.Origin + MouseDirection) -- SW
	-- Basically Mouse.Hit.Position, just raycasting Origin (camera), MouseDirection, and hit would be Hit.P

	local BulletDirection = (MouseRayPosition - FirePoint.WorldPosition).Unit * Distance -- Y
	local BulletRay = workspace:Raycast(FirePoint.WorldPosition, BulletDirection, Params)
	local HitPart = if BulletRay then BulletRay.Instance else nil
	local HitPosition = if BulletRay then BulletRay.Position else MouseRayPosition     
	
	local BClone = Bullet:Clone()
	BClone.Size = Vector3.new(.2, .2, (FirePoint.WorldPosition - HitPosition).Magnitude)
	BClone.CFrame = CFrame.new(FirePoint.WorldPosition:Lerp(HitPosition, .5), HitPosition)
	BClone.Parent = workspace
	
	Ts:Create(BClone, TweenInfo.new(.3, Enum.EasingStyle.Quad), {Transparency = 1}):Play()
	Debris:AddItem(BClone, .4)
end

local function Shoot()
	local Mouse = UserInputService:GetMouseLocation()
	local MousePosition = workspace.CurrentCamera:ViewportPointToRay(Mouse.X, Mouse.Y)
	local DirectTime = os.clock()
	
	ShootEvent:FireServer(MousePosition)
	FireClientBullet(MousePosition)
	--ClientBullet:Fire("Self", Tool, FirePoint, MousePosition)
end

local function OnEquip()
	local Character = Tool.Parent
	
	Params.FilterDescendantsInstances = {Character}
end

local function OnUnequip()
	Params.FilterDescendantsInstances = {}
end


-- Main
Tool.Activated:Connect(Shoot)
Tool.Equipped:Connect(OnEquip)
Tool.Unequipped:Connect(OnUnequip)



Server Script in the tool
-- Services
local Players = game:GetService("Players")

-- Variables
local Tool = script.Parent
local Data = Tool.Data
local Remotes = Tool.Remotes
local FirePoint = Tool.GlockMesh.BulletPoint

-- RaycastParams
local RCP = RaycastParams.new()
RCP.FilterType = Enum.RaycastFilterType.Blacklist
RCP.FilterDescendantsInstances = {}

-- Remotes
local ShootRemote = Remotes.Shoot
local ReloadRemote = Remotes.Reload
local CheckRemote = Remotes.Check
local ReplicateBullet = game.ReplicatedStorage.Remotes.BulletReplication

-- Script Data
local Distance = 300

-- Data

-- Functions
local function HitPlayer(Character)
	print(Character)
end

local function OnShoot(Player, MousePos)
	if Tool.Parent.Name:lower() == "backpack" then return end
	local MouseRay = workspace:Raycast(MousePos.Origin, (MousePos.Direction * Distance), RCP) 
	
	local MouseRayPosition = if MouseRay then MouseRay.Position else (MousePos.Origin + (MousePos.Direction * Distance))

	local BulletDirection = (MouseRayPosition - FirePoint.WorldPosition).Unit * Distance
	
	local BulletRay = workspace:Raycast(FirePoint.WorldPosition, BulletDirection, RCP)
	
	local BulletHit = if BulletRay then BulletRay.Instance else nil
	local BulletPosition = if BulletRay then BulletRay.Position else MouseRayPosition
	
	workspace.DebugPart5.Position = BulletPosition
	
	for i, v in ipairs(Players:GetPlayers()) do
		if v ~= Player then
			ReplicateBullet:FireClient(v, BulletRay)
		end
	end

	if BulletHit and BulletHit.Parent and BulletHit.Parent:FindFirstChild("HumanoidRootPart") then
		HitPlayer(BulletHit.Parent)
	end
end

local function OnEquip()
	local Character = Tool.Parent
	
	RCP.FilterDescendantsInstances = {Character}
end

local function OnUnequip()
	RCP.FilterDescendantsInstances = {}
end

-- Event Functions
ShootRemote.OnServerEvent:Connect(OnShoot)
Tool.Equipped:Connect(OnEquip)
Tool.Unequipped:Connect(OnUnequip)
Local Script in StarterPlayerScripts
repeat task.wait() until game:IsLoaded() 
-- Services
local TweenService = game:GetService("TweenService")

-- Base
local Modules = game.ReplicatedStorage.Modules
local Remotes = game.ReplicatedStorage.Remotes
local Bullets = game.ReplicatedStorage.Bullets

-- Variables
local GunInformationModule = require(Modules.GunInformation)

-- Events
local ClientBullet = Remotes.ClientBullet
local BulletReplicator = Remotes.BulletReplication

-- Functions
local function NormalBullet()
	
end

local function GetParams()
	
end

local function ClientReplication(Player, Tool, )
	if not Tool:IsA("Tool") then return end
	
	local GunInformation = GunInformationModule.GetInformation(Tool.Name)
	local Distance = GunInformation.Distance
	local Bullet = GunInformation.UsedBullet
	
	if Bullet == "NormalBullet" then
		NormalBullet(Firepoint, )
	end
end

local function ServerReplication(Player, Tool, MousePos)
	if not Tool:IsA("Tool") then return end

	local GunInformation = GunInformationModule.GetInformation(Tool.Name)
	local Distance = GunInformation.Distance
	local Bullet = GunInformation.UsedBullet

	if Bullet == "NormalBullet" then
		NormalBullet(Firepoint, )
	end
end

-- Main


-- Event Functions
ClientBullet.Event:Connect(Replication)
BulletReplicator.OnClientEvent:Connect(Replication)

If you are going to be creating and destroying lots of bullets you should look into use the PartCache. It is here:

i dont think ill exactly need it. ill be replicating the bullets through the clients (for now) not the server.

Also sorry for the week long reply, totally forgot i made this post

know this is like 15 days old, still wondering about this though.

1 Like