Physics (Projectiles, Constraints, Movers) - Roblox Advanced Scripting #36 (2025) — Transcript
Full transcript
- 0:00Welcome back to my Roblox advanced
- 0:01scripting tutorial series. My name is
- 0:03Braldiv and in this episode we'll be
- 0:04discussing about physics. And
- 0:08wait, Nubert, what are you doing all the
- 0:11way out here? Shouldn't you be focusing
- 0:13on your scripts and
- 0:15whatnot? Oh my god, he's doing it again.
- 0:19Okay, you know what, Nubert, you really
- 0:20asked for it this time. This is the last
- 0:23straw and now you are going to be out of
- 0:26this world. Goodbye, Nubert.
- 0:32Welcome back. This video is going to
- 0:34cover physics, which allows us to create
- 0:35cool things like this pet follow script
- 0:38that I created where it follows the
- 0:40player behind their back. I've even
- 0:42created a projectile system. If you
- 0:44click wherever you want the fireball to
- 0:46go, then it's going to go in that
- 0:48direction. I've also created a ragd doll
- 0:50system where if you reset your
- 0:51character, then your character is going
- 0:53to be a ragd doll rather than having it
- 0:56explode into a million pieces. I also
- 0:58created a little cool trampoline as well
- 0:59using springs. And all of this can be
- 1:02done using uh physics. Oh man, that is
- 1:06uh that is one powerful uh trampoline.
- 1:09But anyways, all of this can be done by
- 1:10using physics. And this video is going
- 1:13to serve as a broad overview of how you
- 1:15can use physics inside of your Roblox
- 1:17games and how we can script them so that
- 1:20we understand how to create cool systems
- 1:21like this. So with that being said,
- 1:23let's go ahead and go straight into the
- 1:26episode. Now that we understand it,
- 1:27let's implement physics inside Roblox
- 1:30Studio. But before we do, I want to give
- 1:32a basic definition of what physics is.
- 1:34And to explain, physics is essentially
- 1:37the science that studies how things move
- 1:40and interact with the world and other
- 1:43objects within that world. Um, and we've
- 1:47been working with physics actually
- 1:49throughout this entire tutorial guide
- 1:50without us even realizing. And to show
- 1:52you a little example, I'm just going to
- 1:53hit run. And I whipped up a little
- 1:56script that basically creates all these
- 1:59parts that just rain from the sky and is
- 2:01now spreading all around this base
- 2:03plate. And Roblox's physics engine is
- 2:06calculating how these parts are
- 2:08interacting with all of these other
- 2:10parts within the world. And as you can
- 2:12see, my PC is starting to lag a little
- 2:14bit with all of these parts that are in
- 2:15here. But we've essentially worked with
- 2:18physics throughout this entire tutorial
- 2:19guide without us even realizing. And
- 2:21there are some specific properties that
- 2:24we've mostly been using that actually
- 2:25does involve physics. Like uh if I were
- 2:28to insert a part here, by default,
- 2:30anchored is turned off. And what that
- 2:32means is we're applying Roblox's physics
- 2:36to interact with the world in how it
- 2:39would if we were to apply physics to it.
- 2:41So if we were to hit test and hit run,
- 2:42then what's going to happen is it's just
- 2:44going to fall down just like this. And
- 2:46if we were to change its uh anchor
- 2:49property to true, then we're going to
- 2:51ignore Roblox's physics engine so that
- 2:53it's just going to stay stationary. I
- 2:55think uh we understand how this works.
- 2:57And there are even some other properties
- 2:59as well like uh Roblox's gravity that we
- 3:02can change here. So by default, Roblox's
- 3:05gravity is 196. But if we change it to
- 3:08zero gravity, and what's going to happen
- 3:10is all the parts that are inside the
- 3:12game are not going to be affected by
- 3:15gravity. So, as you can see, all these
- 3:17parts are now in zero gravity. And oh my
- 3:20goodness, it is lagging my computer like
- 3:21crazy. But gravity is how we can measure
- 3:25the objects that are inside of our world
- 3:28being pulled down to the the game's
- 3:31core, I guess, if that makes sense. Cuz
- 3:33that is basically what what gravity is.
- 3:34And if we make it zero gravity, then we
- 3:36are not having any gravitational pull
- 3:39towards the center of the world. So,
- 3:41that is basically some properties with
- 3:43physics. And now what I want to cover in
- 3:45this episode is some of the services and
- 3:47objects that Roblox has provided to us
- 3:49to create cool systems. So Roblox's
- 3:51physics engine is very packed with a lot
- 3:54of features that we can use towards our
- 3:56advantage. And one of those features
- 3:58involve mover constraints which are
- 4:01essentially objects that apply force or
- 4:05torque to move one or more parts in a
- 4:08specific direction or multiple
- 4:10directions. Now I am just throwing a
- 4:12bunch of terms out there. So, if I were
- 4:13to quickly explain what's what these
- 4:15concepts mean, think of assembly as like
- 4:18a a part that allows all of its parts
- 4:22that are around it to be connected. And
- 4:24this is the part that's going to be used
- 4:27to apply physics to it. So, since this
- 4:29is one part, there's only one assembly
- 4:31and it's usually in the center of this
- 4:33part. But if we were to have a more
- 4:35complicated model like this uh Nubert
- 4:38model over here, this Nubert model would
- 4:41probably have like 15 parts in it
- 4:43because this is an R-15 character, but
- 4:45it only has one assembly, which is
- 4:47probably somewhere right here in the
- 4:49center of its chest. So, usually when
- 4:51we're working with physics, we're only
- 4:52working with one assembly. So, that's
- 4:54what that means. And then there's things
- 4:56like applying force and applying torque.
- 4:58So force is essentially when you take a
- 5:01part and you move it alongside one
- 5:03direction or multiple directions and
- 5:06when you apply force to it that is what
- 5:08allows it to move in that direction
- 5:10during runtime. And then torque is kind
- 5:13of the same thing but instead it applies
- 5:15rotational force if we were to rotate it
- 5:18during runtime. And that is essentially
- 5:20what that means. So now that we kind of
- 5:23understand those definitions, we can
- 5:24move on to applying these mover
- 5:26constraints so that we can move these
- 5:28parts however we so desire to. And the
- 5:31first object that I want to introduce is
- 5:32called linear velocity. Now there's two
- 5:35ways that we can add mover constraints
- 5:37inside of our game. I'm just going to
- 5:39show you one of them for right now. What
- 5:40I'm going to do is go to model and we're
- 5:42just going to insert a new part just
- 5:44like this. And within this part, what
- 5:47I'm going to do is hit the plus sign and
- 5:49we're going to add an attachment. Now,
- 5:51the reason we're adding an attachment is
- 5:53because we want this attachment to be
- 5:56essentially our assembly. And we don't
- 5:58want the mover constraint to work on the
- 6:00part itself, but instead we want to work
- 6:02on its attachment. So, what we're now
- 6:05going to do is insert a linear velocity.
- 6:10And essentially what linear velocity is,
- 6:12this applies force on an assembly to
- 6:15maintain a constant velocity whether
- 6:18it's in one direction or whether it's in
- 6:21two directions. This is called a plane.
- 6:23Or we can do it inside of a 3D vector
- 6:26where we use all three of these vectors.
- 6:29So what I'm going to do is rename this
- 6:31attachment to attachment zero just to
- 6:34make things more organized. And inside
- 6:36this linear velocity, we need to uh set
- 6:39our attachment zero to the attachment
- 6:42that we just created. So I'm just going
- 6:43to click on this and click on attachment
- 6:45zero. So now it should be activated. Um
- 6:48now there there are some properties here
- 6:49that we can work with, but the most
- 6:51important thing here is this vector
- 6:53velocity uh property. Now velocity is
- 6:56basically the speed at which an object
- 6:59moves in a certain direction. So we have
- 7:02three directions to work with. And if we
- 7:03were to work on the X direction, so if I
- 7:06were to set this to a number like a
- 7:07th00and, we can now see that there's an
- 7:09arrow that's going to be moving in this
- 7:11direction once we hit play. So if I hit
- 7:14test and I hit run, then what should
- 7:16happen is this part is just going to be
- 7:19zooming in the X direction using a
- 7:22constant velocity. So it's going to
- 7:24maintain the same exact speed from where
- 7:27it started to where it ends. And so that
- 7:30is basically what is going on over there
- 7:32and that is how we use linear velocity.
- 7:35Now angular velocity is basically the
- 7:37same thing except it applies torque onto
- 7:40an assembly line which basically is a
- 7:43way of saying that we want to constantly
- 7:45rotate a part in a certain direction. So
- 7:47what I'm going to do is disable our
- 7:49linear velocity and we're going to
- 7:51insert an angular velocity. And I'm
- 7:55going to set attachment zero to our
- 7:57attachment. And what we can do is make
- 8:00our angular velocity go a thousand on
- 8:03the y direction. So it's going to sort
- 8:04of spin around like this. Um, but one
- 8:07thing we also need to do is make sure
- 8:09that for angular velocity, our max
- 8:12torque is set to something that's higher
- 8:14than our angular velocity. So we can say
- 8:16something like
- 8:1810,000 or something just so that we have
- 8:21something in place. So now if we hit
- 8:22run, what we should see is this part is
- 8:26now having a constant rotation on the
- 8:30yaxis. And that is basically what
- 8:32angular velocity does. It's like the
- 8:34linear velocity's counterpart, except
- 8:35this one works with rotation while the
- 8:38other one works with position. The next
- 8:40two mover objects I'm going to introduce
- 8:42are called align position and align
- 8:45orientation. And essentially what these
- 8:48do is they apply force or torque to move
- 8:53two attachments together to kind of
- 8:57mirror each other and reflect on each
- 8:59other's position and orientation. This
- 9:01might make sense once I actually show
- 9:02you what this looks like, but basically
- 9:04what I'm going to do is take this part
- 9:05and I'm going to duplicate it and move
- 9:07it to the right side. And inside of this
- 9:09other part, what I'm going to do is
- 9:11delete its angular velocity and linear
- 9:13velocity. We don't really need them
- 9:14anymore. I'm going to make attachment
- 9:17zero be renamed to attachment one. And
- 9:20what I'm going to do with the original
- 9:22parts angular velocity is disable it
- 9:24because now we're going to apply an
- 9:27align position to this first part just
- 9:30like this. And what we're now going to
- 9:33do is in the attachments category, we're
- 9:35going to set attachment zero to its
- 9:37attachment and then attachment one to
- 9:39the other parts attachment. So now there
- 9:41should be a visual line right over here
- 9:44just like this. And so now what we can
- 9:47do is if we were to hit run then what's
- 9:52going to happen is this part oh it's
- 9:54kind of just uh sliding all around.
- 9:56Okay. I might need to take the second
- 9:58part and anchor it just like this so
- 10:00that it stays in place. So now if we hit
- 10:02run, what should happen is this first
- 10:04part is going to try and follow the
- 10:08second part's position wherever it's at
- 10:10because both of these attachments are,
- 10:13you know, attached to each other. So if
- 10:14I were to move the second part, then the
- 10:16first part should be following the
- 10:19second part because it's trying to match
- 10:20its position. And we can do the exact
- 10:23same thing with align orientation. If we
- 10:26were to hit part uh on the plus sign and
- 10:29if we were to insert an align
- 10:30orientation, let's take attachment zero,
- 10:33attach it to that. Attachment one,
- 10:34attach it to that. So now we have an
- 10:36align orientation and an align position
- 10:39so that we can copy its position and
- 10:42orientation to reflect on the second
- 10:45part just like this. So if I were to
- 10:48rotate the second part, then the first
- 10:50part is going to try and mimic the
- 10:52orientation of the second one. Now, you
- 10:54might be thinking off the top of your
- 10:55head, this looks a lot like a pet
- 10:57following script. And you are right in
- 11:00how you can use align orientation and
- 11:02align position to make this happen. And
- 11:04that's actually what we're going to be
- 11:06uh showcasing right now. Okay. So, I'm
- 11:08going to show you how you would be able
- 11:10to script a pet follow player script
- 11:12using align position and align
- 11:14orientation. So, I just quickly whipped
- 11:16out this pet and what I'm going to do is
- 11:18I'm going to insert three instances
- 11:20inside of this pet. The first thing is
- 11:22going to be our aligned position. The
- 11:24next thing is going to be our align
- 11:26orientation. And then finally, we need
- 11:28an attachment for this pet as well. So
- 11:30I'm going to rename this to attachment
- 11:32zero. And for align position and align
- 11:35orientation instead of using its default
- 11:37to attachment mode, we're actually going
- 11:39to set this to one attachment. And the
- 11:42reason we're going to use one attachment
- 11:43is because we don't need to have two
- 11:46attachments for this to work. And so to
- 11:48show you how we would use align position
- 11:49and align orientation, we essentially
- 11:52want to take the attachment of this pet
- 11:54and we want to set a goal position and a
- 11:57goal orientation and we want to update
- 12:00that every single like let's say
- 12:02millisecond or every single heartbeat if
- 12:04we were to use run service. We want it
- 12:06to be a goal of this character's let's
- 12:10say orientation to look in the exact
- 12:13same direction as the character. So, we
- 12:15want this uh orientation to follow the
- 12:17player's direction. For the position, we
- 12:20would probably want it to be somewhere
- 12:21behind the character, either on the
- 12:23right side or the left side. So, that's
- 12:25something that we would do is we would
- 12:27just calculate the character's position
- 12:29orientation and sort of modify it so
- 12:31that the pet can follow that
- 12:34calculation. And so, we only need one
- 12:36attachment for this to work. And I'm
- 12:38going to show you that when we start
- 12:39scripting it. So, I'm going to hit the
- 12:41plus sign inside of pet and we're going
- 12:42to insert a script. The first thing
- 12:44we're going to do is make reference to
- 12:45our pet by saying local pet equals
- 12:47script.parent. Then we're going to
- 12:49reference its align position and
- 12:51orientation. So we're going to say local
- 12:53align position equals pet.align
- 12:57position. And then we're going to do the
- 12:59same thing for align orientation equals
- 13:02pet.align orientation just like this.
- 13:05And what we want to do is actually make
- 13:07reference to run service. So we're going
- 13:09to say local run service equals game col
- 13:13get service run service just like this.
- 13:16And what we want to do here is say run
- 13:19service colon connect function open
- 13:23close parentheses enter. So we want to
- 13:25update the align position and align
- 13:27orientation every single heartbeat
- 13:29rather than doing it just once. So
- 13:31here's uh something that we can do.
- 13:33Align orientation is actually pretty
- 13:34easy because all we need to do is take
- 13:36the pets align orientations C frame and
- 13:40just set it to be uh let's say the
- 13:42character's humanoid root parts
- 13:44position. That's literally all we need
- 13:45to do and it's going to follow it. So
- 13:47what we're going to do is make reference
- 13:49to our character. And just for
- 13:52simplicity sake, what I'm going to do is
- 13:53just going to hardcode the character
- 13:55location. So we're going to say local
- 13:57character equals game.workspace
- 13:59workspace colon wait for child and then
- 14:02this is just going to be the name of our
- 14:04player which is going to be brawl battle
- 14:05but in this case yours is going to be
- 14:07different with your username and then
- 14:09we're going to say local humanoid root
- 14:10part equals
- 14:13characterhumoid root part just like that
- 14:16and so what we're now going to do inside
- 14:17of here is update the align orientation
- 14:20to match the C frame of the humanoid
- 14:23root part so we're going to say align
- 14:25orientation C frame equals humanoid root
- 14:28part C frame just like this. And this is
- 14:30the only line we need for a line
- 14:32orientation. Now, for the position, uh,
- 14:35this one's going to be a little more
- 14:37tricky because essentially what we want
- 14:39to do is we want to match the humanoid
- 14:41root parts position plus consider the
- 14:44humanoid root parts look vector, which
- 14:46is in this direction, and we want to
- 14:49multiply that by a scaler. So that we
- 14:52take its look vector and we set it
- 14:55backwards like this plus a right vector
- 14:58as well with a scaler so that it moves
- 15:01in this direction as well. Uh it might
- 15:02make sense to you once we uh start
- 15:04scripting this but essentially what
- 15:06we're going to do here is we're going to
- 15:08say align
- 15:10position.position equals we're first
- 15:13going to have it match the humanoid root
- 15:15part position. But then what we need to
- 15:18do is we need to add the look vector
- 15:20plus a scaler. So what we're going to do
- 15:22is say humanoid report frame.look
- 15:25vector. So this is going to give us a
- 15:28vector 3 value. That's going to tell us
- 15:30the direction of where this player is
- 15:32looking, which in this case it's going
- 15:34to be in this direction. So we're going
- 15:36to multiply this by a scaler because the
- 15:38look vector only contains zeros and
- 15:40ones. So if we multiply this by a
- 15:42scaler, then it's going to move back
- 15:45three studs. Essentially, that's like
- 15:46what this is saying right here. And then
- 15:48what we need to do is finally add a
- 15:50right vector as well. So we're going to
- 15:52say plus humanoid root part.
- 15:55Cframe. Vector times 3. Cuz once again,
- 15:59right vector only returns a vector 3 of
- 16:02zeros and ones. So if we multiply by a
- 16:04scaler of three, then it's going to
- 16:07shift to the right by three uh ever so
- 16:09slightly. So that's how we calculate the
- 16:12position of where the pet should be. So,
- 16:15if we now hit test and hit play, then
- 16:17what we should see is this
- 16:20pet. My character was just floating. And
- 16:23that's because I forgot to turn off zero
- 16:25gravity. So, it's 196.2. That's the
- 16:28default gravity. So, if we hit play,
- 16:30then what we should see is this pet
- 16:33should now be following my character as
- 16:36uh like so. Except it is not. Okay. uh
- 16:40we don't want to forget about setting
- 16:42attachment zero to our attachment. And
- 16:45we do the same thing with the line
- 16:46orientation. We don't want to forget
- 16:48about setting those. Those are pretty
- 16:50important. Okay. So now if we hit play,
- 16:52then what we should see is this pet
- 16:55should now be following us as so just
- 16:58like this. So, it's not only following
- 17:01the direction of where the player's
- 17:03looking, but it's also constantly
- 17:06calculating its position to be behind
- 17:08the character and to the right of it
- 17:09slightly, just like so. And so, that is
- 17:11how you create a pet follow script. And
- 17:13I hope that this example has helped you
- 17:15use align position and align orientation
- 17:17for other use cases that you'd want to
- 17:19use inside of your Roblox game. Okay, so
- 17:21mover constraints are pretty cool, but
- 17:23now I want to get into some mechanical
- 17:25constraints that uses Roblox's physics
- 17:28to essentially create these mechanical
- 17:32connections between two or more
- 17:34assemblies. And some examples include
- 17:37ropes, welds, ball sockets, hinges, and
- 17:40stuff like that. But essentially all you
- 17:42would need to do to create these
- 17:44constraints is you can do it through the
- 17:46same method that I've been showing by
- 17:48hitting the plus sign and inserting an
- 17:50attachment and whatever constraint you
- 17:52want to add or we can do this through
- 17:54the model tab as well. So what I'm going
- 17:56to do is insert two parts inside the
- 17:59workspace just like this. And what I'm
- 18:01going to do is go to this tab called
- 18:04constraints with this create dropdown.
- 18:07And we have all of these different
- 18:09movers and mechanical constraints to
- 18:12work with. So, uh, let's say, for
- 18:14example, I wanted to use a rope. So,
- 18:17what it's going to do is we can set
- 18:20where we want the attachment zero to be,
- 18:22and then we can set where we want
- 18:24attachment one to be, which can be over
- 18:25here. And this is another way that we
- 18:28can create a constraint inside of our
- 18:31uh, Roblox game. As you can see, it
- 18:33automatically created attachment zero
- 18:34and attachment one and it created the
- 18:36provided constraint for us right here.
- 18:38So, if I were to let's say move uh
- 18:40attachment one up here and if I were to
- 18:43make this part anchored, then what's
- 18:46going to happen is if we hit run, then
- 18:50there should be a rope that's attaching
- 18:53these two assemblies together so that it
- 18:56creates this mechanical constraint like
- 18:59so. And we can do this with many other
- 19:02constraints as well, but for the sake of
- 19:04this tutorial guide, I'm only going to
- 19:05be showcasing a very few number of them.
- 19:08So, I want to show you the simple
- 19:09ragdoll system that I created when you
- 19:12reset your character, uh, my character
- 19:14is going to look like this, where
- 19:15instead of exploding into a million
- 19:17pieces like any typical Roblox game,
- 19:20instead what I'm doing is I'm using
- 19:22mechanical constraints, specifically
- 19:25ball sockets, to attach all of my 15
- 19:29parts together rather than exploding it
- 19:31into a million pieces. So, I'm going to
- 19:33be showing you what I did inside the
- 19:35script without making this like a
- 19:37step-by-step tutorial guide. Otherwise,
- 19:38this tutorial would be a little too
- 19:39long. But all that this script is doing
- 19:43inside of server script service is we're
- 19:45locating every single player that joins
- 19:47the game and every single character that
- 19:49joins the game. And we want to set this
- 19:51humanoid property called break joints on
- 19:54death to be false. And we want to do
- 19:56this so that the the joints that are
- 19:59connecting all the parts together aren't
- 20:00going to fall apart when the player
- 20:02dies. So what we're doing here is when
- 20:04the character dies, we want to locate
- 20:07every single motor 6 instance. And if
- 20:10you don't know what motor 6 is, uh it's
- 20:12basically an object that allows parts
- 20:15that are connected to each other to move
- 20:18in an animatable way. Um, and so we want
- 20:21to locate all of these motor 6 objects
- 20:24inside the player because there's about
- 20:25like I don't know 14 or 15 of them. And
- 20:27we want to create attachments for each
- 20:29motor 6. And we want to create what's
- 20:31called a ball socket constraint to have
- 20:35these attachments go hand in hand and
- 20:37have them be located within that
- 20:39specific region of the character. And so
- 20:42if you're still confused, literally the
- 20:44whole point of a ball socket constraint
- 20:46is to force two attachments to be in the
- 20:50exact same position while also allowing
- 20:52them to freely rotate uh however they
- 20:55want. So the position is constrained,
- 20:57but the rotation is not. And so that is
- 21:00basically what you need to know about
- 21:02ball socket constraints. Now you might
- 21:04be wondering why there's an if else
- 21:05condition here with the neck
- 21:07specifically. And that's because we
- 21:09don't want to have the neck wobble
- 21:10around because our camera is attached to
- 21:14the player's head. And so it would have
- 21:16like this weird effect if we were to
- 21:18make it happen like that. So if I were
- 21:20to quickly demonstrate what this would
- 21:22look like if I were to just have it so
- 21:25that we have a ball socket constraint in
- 21:27every single motor 6, uh, then what's
- 21:29going to happen is, yeah, look at that.
- 21:31My head is just is just rotating all
- 21:33around. We do not want that to be the
- 21:35case. So that's why we have a special
- 21:38edge case for the neck to have a weld
- 21:40constraint. So we're just simply
- 21:42attaching the head and the upper torso
- 21:44together without any special uh
- 21:46constraint using ball sockets. And so
- 21:48that is a really basic way to create a
- 21:51ragd doll script when the player dies.
- 21:53And I hope that you learned a lot from
- 21:55just me analyzing this script for you.
- 21:57So for this last part of the episode,
- 21:59we're going to be creating a projectile
- 22:01system using physics calculations. So,
- 22:04what I have going on down here is a
- 22:06tool. So, if we equip this tool and I
- 22:08click anywhere in the world using my
- 22:10mouse, then what it's going to do is
- 22:13it's going to shoot a fireball from
- 22:15where the character is to the direction
- 22:18of where my mouse was when I clicked.
- 22:21And it's going to use physics to create
- 22:24this sort of arch motion that involves
- 22:27projectile motion to create this result.
- 22:30And that's what we're going to be doing
- 22:31inside of this episode. But I do want to
- 22:33give a disclaimer saying that we're not
- 22:35going to be focusing on anything related
- 22:37to hit detection or player damaging or
- 22:40VFX or even sound design. We're just
- 22:43going to be focusing on the physics
- 22:45calculations that are involved when
- 22:48creating this projectile motion effect.
- 22:50So with that being said, let's go ahead
- 22:52and create this projectile system. Okay,
- 22:55so to speed things up, I'm going to show
- 22:57you my setup for this projectile system
- 22:59just so that we can get into the server
- 23:01side scripting aspect of it. So what
- 23:03I've done is I've created this
- 23:05projectile that has can collide turned
- 23:07off and this is going to be stored
- 23:10inside of server storage so that we can
- 23:12use it every time we create a
- 23:13projectile. I added a tool to starter
- 23:16pack and I made sure requires handle was
- 23:18turned off because we don't need a
- 23:20handle for this tool. And I just added
- 23:22one local script inside of here. So,
- 23:24basically all this is doing is we want
- 23:27to get the player's mouse. We want to
- 23:29locate this remote event that I put
- 23:32called fireball inside of replicated
- 23:33storage. And we want to get the mouse
- 23:36position of where the player clicked
- 23:39inside of the world. And we're simply
- 23:41just going to send this information to
- 23:43the server so that we can let the server
- 23:46create the projectile and make it move
- 23:48along that direction to where the mouse
- 23:51position was. So that is all I did for
- 23:53the setup. And now we can get into the
- 23:57server side of the scripting. And so
- 24:00basically what I have here is I have the
- 24:03remote event with on server event. We
- 24:05have the player and the mouse position.
- 24:07And we have some variables here. Speed
- 24:09which tells us how fast do we want this
- 24:11projectile to move per stud. And we have
- 24:14this gravity multiplier and max distance
- 24:17which basically tells us that if the
- 24:19projectile goes over the distance then
- 24:22we just want to get rid of it. But I
- 24:23will explain more of this in detail
- 24:25later. So there's three important
- 24:26aspects here with the serverside code
- 24:29right here. So we have the setup then we
- 24:31create the projectile and then probably
- 24:33the most complicated part which is
- 24:35updating the movement every single
- 24:37frame. And I'm going to go over each
- 24:39part as we type all this out. Now, I
- 24:41want you to imagine that this is our
- 24:43player. This is our projectile. And this
- 24:46is the motion that we want this
- 24:48projectile to achieve when we click our
- 24:51mouse. So, we're going to start over
- 24:54here. Uh let's imagine that our player
- 24:56has clicked on their mouse and the mouse
- 24:58position is like somewhere over here.
- 25:00So, this is where the projectile is
- 25:02going to initially start. And with
- 25:05properties like velocity, speed, and
- 25:08direction, we take all of them to
- 25:10determine where it starts and where it
- 25:13needs to go every step of the way as it
- 25:17continues to go further and further with
- 25:20respect to gravity. And we're going to
- 25:23be inching our way to create this
- 25:25projectile motion arch using run service
- 25:29so that it gets updated every single
- 25:31frame. And that is basically what we're
- 25:33going to be achieving here with this um
- 25:36script that we're about to code up here.
- 25:38So going back to our script, we're going
- 25:40to set an origin point which is going to
- 25:43be located on the character's humanoid
- 25:45root part. So we're going to say local
- 25:47origin equals player.c character.h
- 25:51humanoid root
- 25:53part. Just like this. Now, we need to be
- 25:55able to locate a direction of where this
- 25:58projectile should go based on the mouse
- 26:01position and the origin that we've just
- 26:04created over here. So, what we're going
- 26:06to do is say local direction equals
- 26:09mouse position minus origin. So, mouse
- 26:13position is a vector 3 value and we're
- 26:15just going to subtract it with its
- 26:17origin. So, this basically gives us our
- 26:19direction, but it also gives us the
- 26:22distance with that direction. So, we
- 26:25don't want the distance involved with
- 26:27our direction. So, instead, what we're
- 26:29going to do is wrap these in parenthesis
- 26:31and we're going to say unit, which
- 26:34basically gives us a length vector that
- 26:37just tells us the direction that we
- 26:38want. So, this essentially tells us that
- 26:40we don't care about how long this
- 26:44difference is between the mouse
- 26:45position, the origin. We just want the
- 26:48direction as it is. So if I were to help
- 26:50paint this analogy for you, this is
- 26:52basically where the mouse position is.
- 26:55And this is where the origin position
- 26:57is. And if we subtract the two, it gives
- 26:59us a distance. But we don't want the
- 27:01distance. We just want a unit vector,
- 27:04which would be like, I don't know, 0 1 0
- 27:07or 1 0 0 or 0 0 1. That's kind of the
- 27:10basic idea behind it. And so that's what
- 27:11we want to try and get with this
- 27:13direction. We just want the direction.
- 27:15We don't care about how long it is. And
- 27:18next thing that we would need to do is
- 27:19calculate the gravity involved because
- 27:22in order for this to be a projectile
- 27:24motion, we need it so that every single
- 27:26time that we update the the direction
- 27:29and distance and also velocity in this
- 27:31case, we want to make sure that gravity
- 27:34is being affected where the projectile
- 27:36is in this motion. And we can do that by
- 27:39using the workspaces uh gravity
- 27:41property, which you can see down here by
- 27:43default is 196.2. So, what we're going
- 27:45to do is say local gravity equals vector
- 27:493 new open and close parenthesis. And
- 27:52what we're going to put inside of here
- 27:53is uh zero. And what we want is negative
- 27:58workspace.gravity. And then we want Z to
- 28:00be zero. So basically what this is
- 28:02saying is we want to take the default
- 28:04gravity which is 196.2, but we want the
- 28:08the negative version of it because we
- 28:10want it to be affected by gravity going
- 28:12downward, not upward. And so we want to
- 28:14multiply this by the gravity multiplier,
- 28:17which I've specified up here to be 0.25.
- 28:20And the reason we have a multiplier is
- 28:21because this is what allows us to adjust
- 28:25how much the gravity is playing into
- 28:28effect when we shoot the the projectile
- 28:31to go where it needs to go. If that
- 28:34makes sense. Next thing we're going to
- 28:35do is create our projectile. So, we're
- 28:37going to say local
- 28:39projectile equals projectile object,
- 28:43which we declared up here in server
- 28:45storage. We're going to say colon clone
- 28:48open and close parenthesis. We're going
- 28:50to set the parent of the projectile to
- 28:53the workspace.
- 28:55And before we do that, we need to
- 28:58position the projectile to where it
- 29:00should go initially when we create it,
- 29:03which is going to be located somewhere
- 29:05around the player's humanoid viewport.
- 29:06So, what we're going to do is say
- 29:08projectile doc frame equals Cframe new.
- 29:13And we want to specify where it starts
- 29:15and also where we want its orientation
- 29:19to be as well. So, for the position,
- 29:21that's easy. It's just going to be the
- 29:23humanoid reparts position. Now for the
- 29:25orientation, we want to make sure that
- 29:27we have the origin plus the direction,
- 29:31which is what we calculated over here,
- 29:33so that we know where we want the
- 29:36projectile to be facing before we
- 29:38actually shoot it outward. So now down
- 29:40here, we want to update the movement for
- 29:42every single frame when we use run
- 29:44service. So first thing that we're going
- 29:46to do is define a few variables. First
- 29:48thing we're going to define is the
- 29:50velocity. We're going to set this equal
- 29:52to the direction times our speed
- 29:55constant that we created up here. Now
- 29:58speed is measured in studs. So speed
- 30:01basically tells us that we want to
- 30:03travel uh 100 studs every single second
- 30:06for when we have this projectile motion.
- 30:08So if you don't know studs is basically
- 30:10Roblox's uh unit of measurement. These
- 30:13are what studs look like. So in this
- 30:14case these are four studs of
- 30:16measurement. But imagine that this is a
- 30:18hundred of them that looks like this.
- 30:20So, we want the projectile motion to go
- 30:23100 studs per second. And that's
- 30:26basically what this is trying to stay
- 30:27here. So, if we go back to our script,
- 30:30speed basically tells us that we want to
- 30:33travel 100 studs per second. That's
- 30:36basically what this means. So, velocity
- 30:40is what tells us how much speed an
- 30:44object is going to travel in a certain
- 30:46direction. That's basically what
- 30:47velocity is. And so the next thing that
- 30:50we want to keep track of is the current
- 30:52position. So we're going to say local
- 30:54position equals origin because that's
- 30:56where we're initially going to start.
- 30:57And then we're also going to calculate
- 30:59the total distance that this projectile
- 31:01has moved as well. So we're going to say
- 31:03local total distance equals 0. Now this
- 31:07is where things start to get really
- 31:09tricky, but and this is also the last
- 31:11part of uh calculating our projection.
- 31:13So I want you to pay close attention as
- 31:15we as we script this. So what we want to
- 31:18do is create a temporary connection. So
- 31:20we're going to say local connection and
- 31:22then we're going to set connection uh to
- 31:25be equal to run service dot heartbeat.
- 31:29So we're going to run this every single
- 31:31frame per heartbeat and then we're going
- 31:33to say colon connect function open and
- 31:35close parentheses enter. Now there is
- 31:37one piece of information here that we
- 31:38would like to have and that is the delta
- 31:41time. Okay. So going back to this
- 31:43diagram over here, we need to understand
- 31:46how we update the projectiles position
- 31:49and velocity when we're trying to
- 31:52calculate this projectile motion since
- 31:54all of this is being done every single
- 31:57frame for a single second. And if you
- 32:00need a recap on how run service works
- 32:03and how we do run things on a frame by
- 32:05frame basis, let's take this as a
- 32:07reference. So, typically most Roblox
- 32:10games run in 60 frames per second. I'm
- 32:13pretty sure you've heard of this term
- 32:14before. So, 60 frames for every single
- 32:17second that runs. So, if you want to
- 32:19figure out how fast a frame is, we
- 32:22simply just divide 1 by 60. And this
- 32:25will give us about
- 32:280.016. So, every single frame is running
- 32:31for
- 32:320.016 seconds. And so this is happening
- 32:36about 60 times. And uh if we want to be
- 32:40able to go through this entire
- 32:42projectile motion in 1 second, we would
- 32:45have to make this projectile move about
- 32:47four studs every single frame until we
- 32:50can reach the end goal of let's say
- 32:53about 250 studs because that's uh what
- 32:56we decided to set inside of our script.
- 32:59So when we do this, we need to update
- 33:02the next velocity while taking into
- 33:04consideration of gravity and we also
- 33:07need to consider the next position that
- 33:10this projectile is going to move by
- 33:13taking a displacement average from the
- 33:16new velocity versus the old velocity so
- 33:18that we get like an average so that it
- 33:20creates like this smooth arch effect
- 33:23over here. And so we're basically doing
- 33:25this every step of the way. That's the
- 33:27whole idea behind this frame by frame
- 33:29structure. And now we're going to return
- 33:31back to the scripting part. So first
- 33:33we're going to calculate the step
- 33:34velocity by saying local step velocity
- 33:38equals
- 33:39velocity plus our gravity that we
- 33:42created. And we're going to multiply
- 33:44this by delta time. And the reason we're
- 33:46multiplying it by delta time is because
- 33:48we're doing this every single frame so
- 33:50that we can create this smooth arch
- 33:51effect. Next thing we need to do is
- 33:53calculate our step displacement. So,
- 33:55we're going to say local step
- 33:58displacement equals velocity plus step
- 34:02velocity. And we actually want to divide
- 34:05this by two because we want to get the
- 34:07average of the current velocity plus our
- 34:10step velocity. So, we're going to divide
- 34:12this by two. And at the very end here,
- 34:14we're just going to multiply it by delta
- 34:16time so that it's within Roblox's frame
- 34:19by frame loop. So once we've calculated
- 34:21these two, what we need to do is first
- 34:24update our current velocity variable to
- 34:28the new step velocity just like this. So
- 34:31then we need to calculate the next
- 34:33position that this projectile is going
- 34:35to move at by using our position and
- 34:38step displacement. So what we're going
- 34:39to do is say local next position equals
- 34:43position, our current position plus step
- 34:47displacement.
- 34:48and we're going to update the
- 34:50projectiles C frame to reflect that new
- 34:52position. So we're going to say
- 34:55projectile C frame equals C frame new.
- 34:59We're going to throw in the next
- 35:00position as the position. And then for
- 35:03the orientation, we want to make sure
- 35:05that it's the next
- 35:08position plus the velocity unit because
- 35:12we want to have the direction for its
- 35:16orientation.
- 35:18Just like that. We're also going to be
- 35:20updating the position to be the next
- 35:23position. And just as a measure, we're
- 35:26also going to update our total distance
- 35:29to be what whatever it is plus the step
- 35:34displacement magnitude. And we want to
- 35:36make sure we get the magnitude of step
- 35:38displacement, which is basically the
- 35:39size difference between the initial
- 35:42velocity and the next velocity. And at
- 35:44the very end here, we're going to
- 35:46destroy the projectile if the total
- 35:49distance has reached the maximum
- 35:51distance of 250 studs. So let's say if
- 35:54we had the projectile and if it was to
- 35:57go above 250 studs, then we're just
- 36:00going to simply destroy that projectile.
- 36:03So I think this part's pretty
- 36:04self-explanatory. We're just going to
- 36:05say if total distance is greater than or
- 36:08equal to max distance, then we're going
- 36:11to destroy the projectile. So,
- 36:14projectile.destroy. And because we have
- 36:16this connection here, we want to make
- 36:18sure that we disconnect it as well. So,
- 36:19we're going to say connection colon
- 36:23disconnect open close parenthesis just
- 36:26like that. And so, this should pretty
- 36:28much be our entire script. So, if we hit
- 36:30test, I'm going to make sure to move
- 36:32projectile back into server storage. And
- 36:34now I'm going to hit play. So, what we
- 36:36should see is if I press on my tool and
- 36:40if I were to click in a certain
- 36:41direction, then it's going to take that
- 36:44uh projectile and it's going to try and
- 36:46create this projectile motion arch to
- 36:49reach its end goal. And if it goes above
- 36:52250 studs, then it's just going to
- 36:54simply uh destroy itself. Now, this is
- 36:57adjustable. So, if we want to change the
- 36:59speed to let's say 250 studs per second
- 37:03and we make the max distance 1,00 then
- 37:06this projectile is going to move a lot
- 37:08faster if we do it like this. So, as you
- 37:11can see, the projectile is moving a lot
- 37:12faster and we have a lot more range when
- 37:15it comes to how far it can go because we
- 37:18upscaled the max distance as well. And
- 37:21if we want to make this less of an arch
- 37:24motion, then we can make the gravity
- 37:26smaller so that there's less gravity
- 37:28involved when it comes to shooting our
- 37:30projectile. So, I just reduced the
- 37:32gravity uh multiplier. And now, if we
- 37:35were to shoot this, you can see that uh
- 37:37it's kind of going further along more
- 37:40than it needs to because there's less
- 37:42gravity being involved when we're
- 37:44shooting a projectile. And so that is
- 37:47how we can create our own customizable
- 37:49projectile system using the scripting
- 37:51that was involved here. Okay. So to
- 37:53recap everything, we want to use
- 37:55projectile motion to move a projectile
- 37:58from where it starts to where it ends
- 38:02using Roblox's run service to make this
- 38:06happen every single frame so that it
- 38:08creates a smooth arch. So when we start
- 38:11from where it begins at 0 seconds, we
- 38:14want to have this occur 60 times every
- 38:18single second because we want this to
- 38:20happen every single frame. And if we
- 38:21want to move 250 studs, then we have to
- 38:25move this projectile about four studs
- 38:28every single frame just like so. And so
- 38:32the way we do this is let's say our
- 38:36current position and our current
- 38:38velocity is over here. Let's just
- 38:40imagine that this is where it starts. So
- 38:43if we want to keep calculating what the
- 38:46next velocity and what the the next
- 38:48position is going to be, we first need
- 38:50to calculate the step velocity. So we
- 38:52take its current velocity, which is over
- 38:55here, and we want to have it be affected
- 38:58by gravity. And using delta time, that's
- 39:01where it tells us where in this
- 39:03projectile we want this uh new velocity
- 39:07to be. And because we're constantly
- 39:09applying gravity to this velocity every
- 39:11single time as we update it, it's going
- 39:14to keep on going in this little motion
- 39:18over here. As you can see, this is
- 39:20indicated by velocity. It keeps on
- 39:22rotating until we eventually reach the
- 39:24end down here. So that is what is
- 39:27happening when we keep stepping our
- 39:29velocity. We constantly apply gravity to
- 39:32it to make it so that we can reach the
- 39:34next position. Now speaking of position,
- 39:36we need to calculate the step
- 39:37displacement which basically adds our
- 39:40velocity and our new velocity and we
- 39:43average it out to get a distance between
- 39:46the two. So step displacement just tells
- 39:49us how far do we want the position of
- 39:53the projectile to the next one. That is
- 39:56all the step displacement is going to
- 39:58do. And so basically what ends up
- 40:00happening here is we update our new
- 40:03velocity to be the one that's right
- 40:06here. And we also update the next
- 40:09position to be the current position plus
- 40:11the step displacement. So, it's now
- 40:14going to move over here instead of
- 40:16having it be over here. And so, we keep
- 40:20repeating this process over and over and
- 40:22over again until we create this
- 40:24projectile arc to reach the end here.
- 40:27Once it reaches 250 studs, then we're
- 40:29just going to destroy this uh
- 40:32projectile. And so I hope with this
- 40:34explanation you were able to grasp how
- 40:36projectile motion works and how we can
- 40:38use scripting to make physical
- 40:41calculations possible within our
- 40:43scripts. If you're wondering where these
- 40:45projectile motion calculations came
- 40:47from, uh you could just search up
- 40:49projectile motion formulas online and
- 40:52you should be able to apply these
- 40:54formulas into your scripts if you're
- 40:56trying to make a physics calculation. I
- 40:58did not just pull these calculations out
- 41:00of nowhere. And there is meaning behind
- 41:02everything that you do when it comes to
- 41:04having the appropriate calculations for
- 41:07your Roblox game. And this does involve
- 41:10just kind of sitting down and
- 41:11understanding how all of these things
- 41:14work in order for you to understand why
- 41:17these formulas are applied and why does
- 41:20it matter to us for the systems that we
- 41:22are trying to create. There definitely
- 41:24is a learning curve when it comes to
- 41:26knowing how to apply physics inside of
- 41:28your Roblox game, but I hope that with
- 41:31this tutorial, you were able to get a
- 41:33little bit of exposure to how you can
- 41:35apply physics to your scripting. And I
- 41:37would say that if you have made it this
- 41:38far into the tutorial, then I would say
- 41:40that you are definitely up there when it
- 41:42comes to becoming a really great Roblox
- 41:45developer, cuz applying physics to your
- 41:47Roblox game is definitely not easy. So,
- 41:49if you're willing to put in the time to
- 41:51be able to add these systems into your
- 41:53game by applying these complicated
- 41:55formulas into your code, then I think
- 41:56you're definitely on the right track to
- 41:58becoming a great Roblox developer. So,
- 42:00with that being said, that's going to
- 42:02conclude today's episode. I would also
- 42:04like to give a shout out to all my
- 42:05Patreon members. I would like to thank
- 42:07them a lot for their continued support
- 42:09so that I can put out the videos that I
- 42:11enjoy putting out. Now, if you like the
- 42:12work that I put out on this channel and
- 42:14you would like to get access to my
- 42:15scripts, then I encourage you to check
- 42:17out my Patreon page for all the
- 42:19information related to that. But if you
- 42:21can't afford it, then no worries. Uh
- 42:23there are other ways that you can
- 42:25support me with the videos that I put
- 42:26out by leaving a like on this video and
- 42:29also by leaving a comment. I would like
- 42:31to know what you will decide to use
- 42:34physics for inside your Roblox game. So,
- 42:36maybe a comment or two to describe what
- 42:39you're going to do with the knowledge
- 42:40that you've gained from this video would
- 42:42definitely help me a lot. I tend to look
- 42:45at all of my comments, at least for my
- 42:46most recent videos. So, I would really
- 42:48like to know what you're going to do
- 42:49with this knowledge that I provided to
- 42:51you. And with that, this has been
- 42:53episode 36 of the advanced scripting
- 42:55tutorial guide talking about physics.
- 42:57And I will see you in the next
- 43:00one. Take care.
About this transcript
This page contains the full transcript of Physics (Projectiles, Constraints, Movers) - Roblox Advanced Scripting #36 (2025) by BrawlDev, generated from the public captions YouTube serves with the video. The transcript has 7,801 words across 1,092 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to choose a caption track available on the video.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, caption language selection, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.