Linear projectiles

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