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

Hi. As already said in other topics of mine, I am working on a shooter right now. When I got to the point of shooting guns, a question came up: How, where to move the projectile? Of course, plenty of other people faced the same problem and looked for help, though I didn’t understand most methods. The method I know is rather strange?: Change the projectile’s Velocity to the Mouse’s Hit’s lookVector.
In the DevForum, I mostly hear about these 2 Methods:
Raycasting and using Bodymovers. Could anybody please introduce me to them, or link an introduction? I couldn’t find any.

Thanks in advance - Sonnenroboter :slight_smile:

5 Likes

May I suggest you use your favourite browser and enter this search
roblox projectile motion

3 Likes

https://scriptinghelpers.org/blog/modeling-a-projectiles-motion

This article is pretty amazing, it shows you an advanced way of doing what you’re talking about, taking count of gravity.

2 Likes

There’s a lot of documentation on Raycasting, try look some up on the developer hub.
Most games that I know of use Raycasting becuase it allows the server to get an instant check to see if a player has been hit, then deals them damage. Most projectile stuff is done on the client.

If you want to make a projectile move, I’d use a part’s Velocity property and the use of a lookvector or similar to set its flight direction.

projectiles need a way to account for their mass too, so if you use a bodymover, the GetMass() function can be pretty handy. If needs be you can also enable Massless, but be careful when using that.

Also, always make sure bullets are streamed to other clients too, and clean them up after a while to help reduce lag

2 Likes

Though, I might be looking for something simpler as I didn’t understand that article that much.

2 Likes

But then the target would get the damage instantly, and couldn’t even see the bullet, or did I get you wrong here?

In that case, make the bullets faster, or add a delay for the Raycast check. If you want to be realistic you can use a S = D / T measurement to get the time the bullet will take to hit a target or part.

@RamJoT I have already searched on the DevForum for quite a while.
@Blokhampster34 I’m still looking for an introduction. So instead of talking about S = D/T measurements, could you please explain these first? (Or at least the variables?)

If you need some help understanding raycasting, here’s a handy tutorial for making a laser gun:
https://developer.roblox.com/en-us/articles/Making-a-ray-casting-laser-gun-in-Roblox

To use the S = D / T example:

when you have a bullet, make sure you know its velocity e.g. 1000 studs / second

Then, when you have your Ray.new() created (see tutorial) you simply wait a specified time before checking any parts wit by the ray. That way you have to be straregic about shooting.

To work out the specified time you need to wait, use Speed = Distance / Time.
You can get the distance between the gun and the player’s cursor like so:

mouse = player:GetMouse()
distance = (gun.Part.Position - mouse.Hit.p).magnitude -- returns distance between cursor position and gun

We now have the Distance component of the S = D / T equation. We already know our Velocity is 1000
and, since speed = velocity, we can now work out the time we need to wait by re-arranging the equation:

mouse = player:GetMouse()
distance = (gun.Part.Position - mouse.Hit.p).magnitude -- returns distance between cursor position and gun
del = distance / 1000 -- time = distance / speed
delay(del, function()
      -- here is where you check the ray
      local part, position = workspace:FindPartOnRay(YourRayHere, player.Character, false, true)
end)

That is an example of a ray return. It gives you a part that the ray touches, and it’s position.

2 Likes

@Blokhampster34 Ok, I’ll try that out. Do you know any games using that concept though?

I also still would love to hear something the “BodyMovers” method. :slight_smile:

I can’t name any off the top of my head, not being a FPS player myself. I believe you can use a BodyVelocity in pretty much the same way as the normal Velocity method, but I don’t know about over Movers. Hope i helped you out somewhat :smiley:

Yes, you did. Thank you, and have a nice day.

1 Like

I suggested using a browser as that extends your search outside of the forum opening up other sources of information that may be of help.
I am glad to see you have some information to go on.

After you suggested so, I also used the search engine of my choice to inform further. I found nothing though, as the only real resource is the DevForum, and maybe the DevHub.

(Still looking for an BodyMovers introduction)

Recently I have been having the same issue you are facing because there are so many different ways of moving projectiles. I initially though about handling the movement in a for or while loop but I quickly denied that option because I was worried about performance. I was also worried about the projectile not moving smoothly enough.

After reading a post about making a train move I saw that the train was being moved by TweenService. This made me curious about whether this theory would be any good with projectiles. I then had ago using TweenService to create a simple projectile and it turned out nicely in my quick tests.

Making a projectiles with TweenService:
Keep in mind that I haven’t tested this method extensively so I don’t know how well it will perform in a production game. If anyone has any better methods or disadvantages of this method please let me know because I am still testing out this method.

We first need to be able to calculate the time the tween takes. This can be done by using the speed = distance / time triangle @Blokhampster34 touched in earlier. Here is what the triangle looks like.
SpeedDistanceTime
This triangle gives the formulas for calculating speed, distance and time as shown below:

Speed = Distance / Time
Distance = Speed * Time
Time = Distance / Speed

The formula we are most concerned about is the time formula because one of the parameters in TweenInfo is the time the tween takes to complete. According to the formula for calculating time we need to know the speed and distance. You can find the distance by finding the magnitude between the start and end position and you determine the speed. Here is a little code sample demonstrating this:

local Distance  = (StartPosition - EndPosition).Magnitude  -- The distance
local Speed = 20 -- The speed you want the projectile to move
local Time = Distance / Speed -- The time the tween takes

With that out the way I can show you a very basic example of the full code because the rest is self explanatory:

local TweenService = game:GetService("TweenService")

local StartPosition = Vector3.new(0, 0, 0)
local EndPosition = Vector3.new(10, 10, 10)

local Part = Instance.new("Part") -- Creates a new part
Part.Anchored = true
Part.Size = Vector3.new(1, 1, 1)
Part.Position = StartPosition
Part.Parent = workspace

local Distance  = (StartPosition - EndPosition).Magnitude  -- The distance
local Speed = 20 -- The speed you want the projectile to move
local Time = Distance / Speed -- The time the tween takes

local tweenInfo = TweenInfo.new(Time, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 1, false, 5)
local Tween = TweenService:Create(Part, tweenInfo, {Position = EndPosition})
Tween:Play()

This code is obviously not complete because for one the projectile doesn’t face the way it is moving.


I haven’t tried out using BodyMovers to make projectiles so I am not one hundred percent sure of a way to make a projectile using them. However I am fairly confident you will need to use the triangle I shown above in some way.

3 Likes

@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?