Help with Optimizing Raycast Projectiles

I want to make Bullets for my game, and I’ve made a raycast projectile script, however, when theres more then 3 of them at once it gets very low FPS

ive tried changing the model of the projectile
everything is on the client aswell
i dont know what to do

Heres the script

local RS = game:GetService(“RunService”)
local CS = game:GetService(“CollectionService”)
local Explosions = require(game.ReplicatedStorage.GlobalModules.Explosion)
local Projectiles = {}
local IgoreTable = {}
local module = {}

function CreateProjectile(Model,Origin,Target,Size,Speed,Explosive,Ignores,Damage)
local Projectile = game.ReplicatedStorage.Projectiles:FindFirstChild(Model):Clone()
Projectile.Position = Origin
Projectile.Parent = workspace
Projectile.CFrame = CFrame.lookAt(Origin,Target)

local Bullet = {
	BulletObject = Projectile,
	Origin = Origin,
	LastPos = Origin,		
	StartTime = tick(),
	Direction = Projectile.CFrame.LookVector*Speed,
	CurrentPos = Vector3.new(),
	Size = Size,		
	Explosive = Explosive,
	Ignores = Ignores,
	Damage = Damage
}

table.insert(Ignores,Bullet.BulletObject)
table.insert(Projectiles,Bullet)

return Bullet

end

function Step()
for index,Bullet in Projectiles do

	Bullet.BulletObject.Destroying:Connect(function()
		if table.find(Projectiles,index) then
			table.remove(IgoreTable,Bullet.BulletObject)
			table.remove(Projectiles,index)
		end
	end)
	local Distance = (Bullet.Origin - Bullet.CurrentPos).Magnitude
	if Distance >= 500 then
		Bullet.BulletObject:Destroy()
	end
	local TimeLength = (tick()- Bullet.StartTime)
	Bullet.CurrentPos = Bullet.Origin + (Bullet.Direction*TimeLength)		
	local Params = RaycastParams.new()
	Params.FilterType = Enum.RaycastFilterType.Exclude
	Params.FilterDescendantsInstances = {Bullet.Ignores,IgoreTable}
	Bullet.BulletObject.CFrame = CFrame.new(Bullet.CurrentPos,Bullet.LastPos) * CFrame.new(0,0,-(Bullet.LastPos-Bullet.CurrentPos).Magnitude/2)
	local Cast = workspace:Spherecast(Bullet.LastPos,Bullet.Size,Bullet.CurrentPos-Bullet.LastPos,Params)

	if Cast then
	if Bullet.BulletObject.Parent == workspace then
		table.remove(Projectiles,index)
		Bullet.BulletObject:Destroy()
		if Bullet.Explosive == true then
				
				

				if Cast.Instance.Parent:FindFirstChild("Humanoid") then
					local Humanoid = Cast.Instance.Parent:FindFirstChild("Humanoid")

					game.ReplicatedStorage.Events.Damage:FireServer(Bullet.Damage,Humanoid,Cast.Instance,Bullet.Direction,Cast.Position,Humanoid:HasTag("Player"))
					
					
				end	
				Explosions.Explode(Cast.Position,25,math.round(Bullet.Damage/2),0)
				
			else
				if Cast.Instance.Parent:FindFirstChild("Humanoid") then
				local Humanoid = Cast.Instance.Parent:FindFirstChild("Humanoid")
				
			game.ReplicatedStorage.Events.Damage:FireServer(Bullet.Damage,Humanoid,Cast.Instance,Bullet.Direction,Cast.Position,Humanoid:HasTag("Player"))
	
				end	
				end			
		end
	end		
	Bullet.LastPos = Bullet.CurrentPos	

end

end
function module.Fire(Model,Origin,Target,Size,Speed,Explosive,Ignores,Damage)
CreateProjectile(Model,Origin,Target,Size,Speed,Explosive,Ignores,Damage)
RS.RenderStepped:Connect(Step)
end
return module

1 Like