Can someone introduce me to the different ways of moving a projectile?

@waterrunner Thank you, very informing.

But don’t the methods utilizing the speed triangle have the problem of the target moving?
Maybe the player moves a bit behind, the moment the shot is given. Then the shot would stop right in front of the player. Guns with a high bullet speed wouldn’t face that problem, but things with a lower bullet speed (rocket launcher, sticky launcher, toaster, etc) would have that problem, or am I wrong? Is there any way to fight against that problem?

Edit: Would using the Touched event work? I could stop the bullet, when it hits something.

This is a really good point and something that I have overlooked and not had much experience in fixing. I do however have some theories about fixing this issue but most of them haven’t been properly tested so I wont be posting them. I don’t really want to spread false information so I am going to let another developer explain a solution to this problem.

I am still learning all this stuff so I am curious to know a good and reliable solution to this problem. I would greatly appreciate it if someone could explain a solution.

1 Like

Do you think using the projectile’s touched event would be possible?

The Touched event fires when a part comes in contact with another part.

I could simply set the Velocity/use a BodyMover and destroy the projectile after some time. That should fix our problem.

I could be overthinking this but I can see this working and not working. Here is my thought process:

The client always has to do some sort of input to say they are about to fire the projectile so this means you need to have at least one network call to let the other clients know you are firing the projectile. Network calls take a certain amount of time to go through so from when you have clicked to when the rest of the clients see you have clicked there is a delay. The delay can vary between clients depending on their connection. This means any projectile you fire wont always be in sync with the other clients.

Lets say you fire a projectile and you detect when the projectile touched a player using the touched event. You will have the risk of one client seeing one thing and the other not. One client could see the projectile hitting the player and the player being hit may not see the projectile hitting them.

However another method could be to handle the movement of the projectile on the client firing it. Then once the projectile comes in contact with something let the server know so that it can verify it and perform the correct action depending on what the projectile hit. This method could help eliminate the issue with one client seeing one thing and another seeing something else. This method does have its disadvantages so I am not sure if this is the best way to handle projectiles.

Maybe using BodyMovers are the best option because they use the Roblox physics engine. Some of the issues that I have described could be eliminated by doing this. I haven’t used BodyMovers for a long time and never used them for projectiles yet so i will need clarification on how good they are for projectiles.

From what I have been reading the touched event isn’t reliable so you shouldn’t be using it for projectiles. Instead people have been suggesting to use Ray Casting. However this is best kept for a discussion on another topic.

@MrLegendaryDoge
If I updated the bullet’s position every 0.1s, it wouldn’t look smooth.
If I bound the Bullet movement to every Render step, I’m worrying about performance.

From further research on the DevForum, I should never use the Touched event as it’s unreliable. I should use RayCasting instead. How could I do that, without having the speed triangle issue discussed further up in this topic?

Here’s a pretty cool module that I’ve tinkered with, it’s also great to learn from especially regarding the physics/math surrounding projectiles: Making a combat game with ranged weapons? FastCast may be the module for you!

Edit: Whoops meant to reply to OP

Stepped will get you a good enough result, as for performance it can be situational. PartCache, for all your quick part-creation needs , is great for optimizing situations like tons of bullets flying around.

One method used is to let the server only do the calculations (like hit detection), and the client to draw/simulate the bullet visually.

I have seen it everywhere. FastCast, FastCast, FastCast. I want to do everything for myself, because I think that makes me actually learn it. I also don’t want to rely on some third party module.

Well there are lots of ways to learn something. I recommended FastCast not just as something you can use, but like I explicitly stated, it’s a module that is great to learn from in terms of simulating projectiles in Roblox’s context. The source is entirely open.

Could you give me an example of what making a projectile using RenderStepped would look like, or explain it a little further? (Also stop advertising EtiTheSpirit’s modules, lol)

I don’t have any readily digestable snippets that are better to learn from than FastCast (that I know of). If you just want an example, it’s not hard to draw up yourself, or find something in the toolbox to study. The simplest example of a projectile w/ renderstepped is simply creating a part, then in a RenderStepped CFraming it in a certain direction.

Lastly, I don’t see anything wrong with “advertising” great contributions to the devforum to help explain content.

@Silentude I’ll have a look at FastCast, though I still fear performance issues with many bullets moving.

The advertising part was a joke. I made it because both modules are by EtiTheSpirit and I didn’t ask for PartChache.

So, does anyone passing by here happen to know a method of using Body movers? I’m fairly certain that there are ways around the Speed triangle and the Touched event sucking problem. I’d really appreciate that since Free Models (as almost always) don’t give anything useful. Thanks. :slight_smile:

If it’s of any help to you, the old module – which used a lower performing object model, mind you (the modern version is FAR faster) – could fire over 600 bullets per second without any lag at all. Of course, Roblox’s replication won’t like you if you spam an event that hard, but the script itself is fast.

Ok, but I’m assuming every Client would have to move the bullets itself, right?
I don’t think to replicating the bullet’s position every to all clients heartbeat is a good idea…

I’d have to fire a Remote a lot then, and that might cause the projectile to appear earlier than for other clients.

Ok so I’m on mobile here but I can point you in the right direction for bodymovers.
So you start with creating a bodyVelocity and make it face the part with some CFrame math(not tested)
local speed = [speed here]
local bv = Instance.new(“BodyVelocity”)
bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bv.Velocity = (CFrame.new([gun pos], [mouse.Hit pos]).LookVector * Vector3.new(speed, 0, speed) ) + Vector3.new(0,[y velocity to put on bullet], 0)
bv.Parent = [bullet]
I can’t guarantee it works and you’ll have to fiddle with the speed and y velocity, but here is the base of body movers and bullets
Edit: why won’t you work darn codeblicks

Thanks. Looks fine to me, though I probably could’ve done that myself. (Probably, :slight_smile: )
Do you have any idea, how hits could be detected, as that’s the actual problem with Bodymovers.

I’m reading a lot of posts using instancing/bodymovers, but it should be known that in larger-scale games, instancing can become pretty heavy on memory, especially in games with large player count.

For projectiles, I use this function: (units = amount of units, per frame, that the projectile will travel; also note that the projectile should be Anchored and CanCollide == false.)

game:GetService("RunService").Heartbeat:Connect(function()
    projectile.Position = projectile.Position + projectile.CFrame.LookVector * units
end)

There is nothing wrong with using instancing, but I prefer using this method as it’s a lot easier to manage and control. Additionally, bullet dropoff is possible by multiplying the x-component of the projectile using CFrame.Angles().

In order to detect collisions with your projectile, check out this article that uses the GetTouchingParts() function. It’s (arguably) more accurate than .Touched and less expensive than Raycasting.

Hope this helped! :smiley:

6 Likes

You just solved all problems that came up in this topic, without creating any.

Thank you very much, I really appreciate your help. :smile:

1 Like

Hello, I am the person who wishes to debate this, specifically the second one.

The expense of raycasts increases depending on the length of the cast. Otherwise, firing off rays holds a negligible cost. You can fire off hundreds of rays per frame with no noticeable expense or performance drop. :slightly_smiling_face:

1 Like