For big projectiles ( not physics simulated it’s just linear ), what’s the best way to detect anything that hits it?
I looked to modules like FastCast but I am not sure if it’s good with Big projectiles.Also, how can I make it move smoothly for every player.
2 Likes
I would recommend shape cast and using client projectiles.
3 Likes
Make it smooth with TweenService or CFrame.lerp. Try using physics, or making a detection loop, raycast, or a hacky unanchored weld/hitbox attachment with .Touched (use as a last resort, please).
1 Like
Smooth as in if I make the server handle it, it won’t be smooth enough.
1 Like
And how do I replicate them to every other client.
1 Like
Use :FireAllClients() the client will only visualize the projectile while the server handles hit detection. I recommend searching up for more info.
1 Like
make 2 projectiles. 1 invisible server sided one to detect hits to kill, and 1 client sided one for every player in the server for visuals
when it gets spawned by server initially, fireallclients(startingprojectile position)
The server script should look like this:
–server
spawn projectile
fireallclients(projectile position)
move projectile
hit detection
Client script should look like this:
–Client
event receieved(projectile position)
move projectile
2 Likes
When the client wants to spawn the projectile, create it on the client immediately. Fire a remote to the server with the spawn position and position / CFrame where the client was aiming, and then have the server create an invisible projectile for authoritative hit detection. I recommend parenting the server’s projectile under the workspace’s Camera because instances placed there do not replicate to clients.
The server then tells all clients (FireAllClients or for loop) that they need to spawn a projectile of a certain type at the same starting position and goal position (either don’t fire to the client that spawned it, or have them ignore the event).
Now everyone can move the projectile with either a physics constraint like LinearVelocity or setting its position in a RunService loop like:
RunService.Heartbeat:Connect(function(dt)
projectile.Position = projectile.Position + projectile.CFrame.LookVector * (studsPerSecond * dt)
end)
For hit detection, use the spatial query methods in WorldRoot. Since you’re using a projectile with a large hitbox, use either Shapecasting or GetPartsInPart / GetPartBoundsInBox (less accurate but more performant) in a RunService loop.
All the clients and the server should run the hit detection to delete the projectile when it contacts something or play some purely visual effect. When the client’s (to be clear, the one that spawned and “owns” the projectile) spatial query loop returns a hit instance, fire the server with information about the point of contact. The server makes sure that the information isn’t wildly inaccurate (e.g. it’s not 2000 studs away or behind a wall), deals damage or does something important if the information is fine, and fires all clients with the same information.
2 Likes
If I did this the projectile visualize will differ from a client to another most likely the player will see he touched somethng yet another player will assume it’s too far since it delayed the moment it fired the projectile. Moreover, is there a way to do it with network ownership
1 Like
this applies for your method too.
1 Like
Network ownership for physics objects on the server defaults to whoever is closest to said object (if i’m not mistaken) so whoever is closest to the projectile will see it the smoothest, if you want to you can set the ownership to the player who spawned it (if it’s a bullet type thing)
1 Like
If you’re worried about synchronization, send workspace:GetServerTimeNow() through all the remotes, and when the clients receive them, they get the offset by subtracting from the current time and then spawn the projectile where it would be after travelling for time equal to the offset.
In my use cases, the time difference is usually small enough with average ping that it would barely make a noticeable visual difference or discrepancy, so make sure that synchronization is actually a problem that you need to resolve.
Also, network ownership is not a very good solution for projectiles. Set it to the server, and it will appear laggy for all the clients. Set it to a client, and it will appear laggy for all the other clients. Set it to shared, and things get ugly when ownership changes.
1 Like
You can’t make it smooth for every player, if you wish to do it on the server, good luck with it hogging server memory. (that is if you aim for a server-sided casting that handles both hit detection and visualization)
If you still want the server to be fully authoritative of the hit detection, try out SecureCast. If not, handle hit detection to the caster and replicate the projectile to everyone with RemoteEvent:FireAllClients()
and UnreliableRemoteEvent:FireAllClients()
1 Like
then how would I sync both hit detection and the projectile object on every other client?.
1 Like
Can you elabrote on your workspace:GetServerTimeNow()
method
1 Like
Also why when setting network owner ship to a client it appears good to them and not other players, isn’t it just better because you are letting the client handle the projectile position and letting other players know it rather than doing everything on a possibly laggy server.
Moreover, client / server update rates are different yeah? so wouldn’t that let them not sync even if they start togther?
1 Like
You can pretty much do hit detection on the server and visualize the projecites on each client (doing their own hit detections too—though faulty).
1 Like
btw why would using roblox phyiscs like linear velocity not be the solution don’t they replicate them well?
1 Like
The projectile must be unanchored to do so, thus giving extra work for Roblox’s internal physics (can be mitigated by turning on the Massless property but you have to calculate gravity by yourself)
And since we’re talking about replication, one might see their own projectile lagging behind, and it does not account the fact the lower your fps = the slower the projectile, using plain CFrames and using any RunService’s methods’ deltaTime
is much more reliable.
1 Like
I meant directly putting a linear velocity in a server and doing the detections there, as in roblox linear velocity should handle it well for every client.
1 Like