((Please don’t link Fastcast as I’m attempting to find a solution without.)
I’m looking into projectile management on a large scale - I’ve watched a fair few tutorials on both YouTube and DevForum but all seem to be using .Heartbeat() on the Server and others are using BodyConstraints for the physics.
To summarise, I’m working on SpellCasting & want the Projectiles to be Moved from PointA to PointB whilst checking for obstructions Infront of them. I’ve got a basic method of doing this utilities :FireAllClients and loading the Projectile & Movement ClientSide by utilising CollectionService to see when a new SpellPart is added.
However I’m seeing an increase in Pings whenever this occurs and don’t want to create immense lag from Projectiles. (Roughly about 15-20 being fired every 2-3 seconds by the Players ingame.)
Does anyone have any suggestions or concepts that I could build on? This is a method that has baffled me for years now and I’m looking for finally solve it efficiently.
Projectiles are created and managed on the Client.
I handle the remotes by:
Wand tool > RemoteEvent in replicatedStorage > Confirms data > FiresAllClients on another remote event. Then from there it’s handled on the client.
How much data are you sending? Is it just position, direction, and id of was shot? I remember FE gunkit was sending a whole table of effects and settings which easy reached the 50 kbps data limit. Speaking of which what is the maximum kbps you get while shooting the spell?
I’m also sending the wand Tools data, i.e. the tool itself and the caster?
And not too sure on the Kbps however the pings gradually increase from 30 to 50 and fluctuate between 50-60
local RunService = game:GetService("RunService")
local bullet = script.Parent
local previousPosition = bullet.Position
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {bullet}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
RunService.Stepped:Connect(function()
local origin = bullet.Position
local direction = (origin - previousPosition) * (origin - previousPosition).Magnitude
local raycast = workspace:Raycast(origin, direction, raycastParams)
if raycast then
print("hit")
end
previousPosition = origin
end)
Would this be more performant than CFrame? Or would there be a noticeable stutter when first creating to projectile and setting the NetworkOwner to the Player?
I’ll give that a go when I’m home
Do you possibly have any snippets of code I can use as reference and build on as an example, please?
It’s fine if not!
Thank you! I’ve looked into it however due to the physics I can’t really work with it - I’m looking for my spells to be linear in direction as opposed to gravity induced.
I’m continuing to work on this ~ I’ve attached below code that I’m currently working on - This is just an example of producing projectiles & movement.
Issue it that the only way I can get an accurate detection is by having the Speed and the RaycastDistance both match - The issue with this is that if the Speed is ‘20’ then that Raycast is capable of hitting targets from 20 studs away - Whereas those 20 studs could be crucial for a defence.
local Core = { ... }
local Server, Script = game, script
local Folder = Instance.new('Folder')
Folder.Parent = workspace
local RaycastParam = RaycastParams.new()
RaycastParam.FilterType = Enum.RaycastFilterType.Exclude
RaycastParam.FilterDescendantsInstances = {Folder}
local Speed = 5
Server:GetService('RunService').PreSimulation:Connect(function(dt, ...)
for __,Part in (Server:GetService('CollectionService'):GetTagged('Projectile')) do
local LastPos = Part.Position
local result = Server:GetService('Workspace'):Raycast(LastPos, Part.CFrame.LookVector * Speed, RaycastParam)
if not result then
Part.CFrame *= CFrame.new(-Vector3.zAxis * Speed)
else
Part.Position = result.Position
Part.Transparency = 1
Part:FindFirstChild('ParticleEmitter', true):Emit(1)
Part:RemoveTag('Projectile')
end
end
end)
while Core do
task.wait(0.25)
local Part = Script.Part:Clone()
Part.Size = Vector3.new(1, 1, 1)
Part.Anchored = true
Part.CanCollide = false
Part.CanTouch = false
Part.CanQuery = false
Part.CastShadow = false
Part.Position = Vector3.new(0, 18.5, 227) + Vector3.new(math.random(-45, 45), math.random(-16, 16), 0)
Part.BrickColor = BrickColor.random()
Part.Parent = Folder
Server:GetService('Debris'):AddItem(Part, 5)
Part:AddTag('Projectile')
end
return Core
Sorry to bump this again - Just one final question.
In terms of using the .Stepped - Is it best to filter through a table of the projectiles within CollectionService i.e. for __,Part in (Service) do or to simply allow each projectile to generate their own .Stepped function?