So far I have a projectile system that when shooting a bullet, ->creates a coroutine ->>The coroutine then creates the Projectile -->The coroutine then also casts rays infront of the projectile --->it moves it if it can
A unique coroutine is made for every bullet, but after shooting for a while, there is a huge drop in frames, but it only ever happens when I am firing bullets.
Is there any other method I could use to help me simulate projectiles in this way? Because I'd like to avoid the lag spikes as much as I can.
StarterPlayerScripts -MainScript --BulletModule;
local Camera = game.Workspace.CurrentCamera
local module = {}
local Player = game.Players.LocalPlayer
function CAST(start,targ,ign)
local dir = (targ - start).unit
local newray = Ray.new(start,dir.unit*50)
local hit,pos = game.Workspace:FindPartOnRay(newray,ign)
return hit,pos
end
function Collide(Part,Position,dam,Bull)
if Part:IsDescendantOf(Player.Character)~=true and Part.Parent:findFirstChild("Humanoid") then
local human = Part.Parent:findFirstChild("Humanoid")
if human then
print(Part.Name)
--human:TakeDamage(dam)
local K = Instance.new("Vector3Value")
K.Value = ((Bull.CFrame*CFrame.new(0,0,-100)).p-Bull.Position).unit
print(K.Value)
K.Name = "Kill"
K.Parent = Part
human.Health = human.Health - dam
game.Debris:AddItem(K,.3)
if human.Health == 0 then
if Part.Name == "Head" then
Part.Transparency = 1
Part.Decal:remove()
local Blud = script.Blud:clone()
Blud.Parent = Part
end
end
else
end
end
end
function Bullet(start,target,INFO,ignore)
local ProjInfo = {}
local function SetupProj(Config,Default)
if INFO[Config] then
ProjInfo[Config] = INFO[Config]
else
ProjInfo[Config] = Default
end
end
SetupProj("SPD",100)
SetupProj("DMG",10)
SetupProj("TYP","Bullet")
SetupProj("DROP",-.01)
SetupProj("SPR",3)
local hitthing
local dir = (target - start).unit
local collide = nil
local collidePos = nil
local collideSurf = nil
local distance = (target - start).magnitude
local length = ProjInfo.SPD/20
local rayPart
local Sound
local Light
local Trail
if ProjInfo.TYP == "Bullet" then
rayPart = Instance.new("Part")
rayPart.Name = "RayPart"
rayPart.BrickColor = BrickColor.new("Bright yellow")
rayPart.Transparency = 0.3
rayPart.Anchored = true
rayPart.CanCollide = false
rayPart.TopSurface = Enum.SurfaceType.Smooth
rayPart.BottomSurface = Enum.SurfaceType.Smooth
rayPart.Material = "Neon"
rayPart.Size = Vector3.new(.2, .2, 2.8)
rayPart.Parent = Camera
Trail = script.Trail:clone()
Trail.Parent = rayPart
Sound = script.Sound:clone()
Sound.Parent = rayPart
Light = Instance.new("PointLight",rayPart)
Light.Color = Color3.new(206/255,80/255,8/255)
elseif script:findFirstChild(ProjInfo.TYP) then
rayPart = script:findFirstChild(ProjInfo.TYP):clone()
rayPart.Parent = Camera
Trail = rayPart:findFirstChild("Trail")
Sound = rayPart:findFirstChild("Sound")
Light = rayPart:findFirstChild("Light")
end
rayPart.CFrame = CFrame.new(start,target+Vector3.new(math.random(-ProjInfo.SPR,ProjInfo.SPR),math.random(-ProjInfo.SPR,ProjInfo.SPR),math.random(-ProjInfo.SPR,ProjInfo.SPR)))
Sound.Pitch = 1+(math.random(-4,4)/10)
Sound:Play()
local prevPosition = start
local KillBull = coroutine.wrap(function()
wait(3)
rayPart.Anchored = true
rayPart.Transparency = 1
Trail.Enabled = false
Light.Enabled = false
if rayPart:findFirstChild("Out") then
rayPart.Out:Play()
end
game:GetService("Debris"):AddItem(rayPart,2)
end)
KillBull()
if (distance > length) then
repeat
local bulletFront = (rayPart.CFrame * CFrame.new(0, 0, -1)).p
local dir = (bulletFront - rayPart.CFrame.p).unit
local position = prevPosition + (dir * length)
local hit, endPos = CAST(rayPart.CFrame.p, bulletFront, ignore)
local newDistance = (endPos - prevPosition).magnitude
collidePos = endPos
collide = hit
if (newDistance < length) then
--break
hitthing = true
end
local bulletDistance = (position - prevPosition).magnitude
rayPart.CFrame = CFrame.new(prevPosition, position) * CFrame.new(0, 0, -bulletDistance / 2)*CFrame.Angles(math.rad(ProjInfo.DROP),math.rad(-0),math.rad(-0))
prevPosition = position
game:service'RunService'.RenderStepped:wait()
until hitthing == true or rayPart == nil or rayPart.Parent == nil
if rayPart then
rayPart.Anchored = true
rayPart.Transparency = 1
Trail.Enabled = false
Light.Enabled = false
if rayPart:findFirstChild("Out") then
rayPart.Out:Play()
end
game:GetService("Debris"):AddItem(rayPart,2)
end
else
local position = prevPosition + (dir * length)
local hit, endPos, Surface = CAST(start, position, ignore)
local distance = (endPos - start).magnitude
local newDistance = (position - start).magnitude
rayPart.Size = Vector3.new(0.1, 0.1, distance)
rayPart.CFrame = CFrame.new(start, endPos) * CFrame.new(0, 0, -distance / 2)
game.Debris:AddItem(rayPart, 0.1)
collidePos = endPos
collide = hit
end
if rayPart then
Collide(collide,collidePos,ProjInfo.DMG,rayPart)
end
end
function module.RAY(start,target,INFO,ignore)
local shoot = coroutine.wrap((function(start,target,INFO,ignore)
Bullet(start,target,INFO,ignore)
end))
shoot(start,target,INFO,ignore)
end
return module

2 comments
Can you include your code, or at least its skeleton, so we can have a better idea of exactly what you need?
Here is the Module's code: https://docs.google.com/document/d/1TrwgTgYWm7ziSMktzuni6f4ENRlmWOqs3ucpnyPzlz4/edit?usp=sharing