-
What do you want to achieve?
I want to allow players to fire a large amount of projectiles without causing (mostly fps) lag. -
What is the issue? Include screenshots / videos if possible!
I allow players to build their own spacships and they can place weapons on them. When a lot of projectiles are fired, client side framerates drop massively. I feel like they are dropping way lower than they should with the amount of bullets than I am generating.
- What solutions have you tried so far?
I am using the FastCast module. Whenever a player fires their weapons I simultaneously render the projectiles on the client using fast cast, and fire a remote event to the server. The server notifies all clients and they then render the bullets (unlesss this client is the one who fired, since he has already rendered them before firing the remote event).
I have tried to include the relevant pieces of code.
CLIENT_SIDE
local BULLET_UPDATE_RATE = 1 / 30 * 1000
-- TODO: check out if this can be more effiicent
local caster = FastCast.new()
local module = {}
local bullet = Instance.new("Part")
bullet.Anchored = true
bullet.Size = Vector3.new(1, 1, 3)
bullet.BrickColor = BrickColor.Red()
bullet.CanCollide = false
bullet.Material = Enum.Material.Neon
module.replicateBulletHelper = function(origin, directionWithMagnitude, velocity, blacklist)
local part = bullet:Clone()
part.Parent = workspace
part.CFrame = CFrame.new(origin, origin + directionWithMagnitude.Unit)
local ray = caster:FireWithBlacklist(origin, directionWithMagnitude, velocity, blacklist, part)
local epochDisplacement = 0
caster.LengthChanged:connect(
function(origin, lastPoint, rayDir, displacement, cosmeticBulletObject)
epochDisplacement = epochDisplacement + displacement
if epochDisplacement < BULLET_UPDATE_RATE then
return
end
epochDisplacement = 0
cosmeticBulletObject.Position = lastPoint
end
)
caster.RayHit:connect(
function(hit, point, normal, material, cosmeticBulletObject)
cosmeticBulletObject:Destroy()
end
)
end
SERVER SIDE
function Ship:fireManualWeapons()
for index, manualWeapon in pairs(self.manualWeapons) do
local barrel = manualWeapon.component:getModel():FindFirstChild("Barrel")
if not barrel then
error("Tried to fire manual weapon with no barrel")
end
local range = self.range
local direction = barrel.CFrame.LookVector
local directionWithMagnitude = direction * range
local velocity = self.velocity
local origin = barrel.Position
local blacklist = { manualWeapon.component:getModel() }
self.networkManager:getServerToAllClientsEvent("replicate_bullet"):FireAllClients(origin, directionWithMagnitude, velocity, blacklist, self.owner.UserId)
local ray = manualWeapon.caster:FireWithBlacklist(origin, directionWithMagnitude, velocity, blacklist)
manualWeapon.caster.RayHit:connect(function(hit, point, normal, material)
-- do actual hit detection here
end)
end
end
I am assuming i am performing some inefficient logic somewhere, but I cannot seem to nail it down. So i guess my question is, how can i optimize this?
Thanks in advance!
