Raycasting (Guns, Visualizers, Shapecasts) - Roblox Advanced Scripting #37 (2025) — Transcript
Full transcript
- 0:00This is raycasting. A simple to
- 0:02understand idea yet very difficult
- 0:05concept to implement on Roblox. And it
- 0:08has many practical use cases as seen in
- 0:11very popular Roblox games. Think of
- 0:13games like blocks fruits where they have
- 0:15projectile based abilities that use ray
- 0:17casting or games like bedwars to
- 0:19determine what blocks can be destroyed
- 0:22by the players when they click on them.
- 0:24Those only scratched the surface of what
- 0:26you can do with ray casting, but in
- 0:28general, it's one of the most popular
- 0:29Roblox scripting concepts ever. My name
- 0:32is Baldev and in this advanced scripting
- 0:34tutorial episode, we'll be covering what
- 0:36ray casting is and how we can implement
- 0:38this inside of our own Roblox games. And
- 0:41by the end of this video, my goal is to
- 0:43equip you with the knowledge to
- 0:44understand ray casting on a fundamental
- 0:47level and can script ray casting for
- 0:49your own systems. But before we do,
- 0:51let's think about this for a minute. The
- 0:53first thing we want to ask ourselves is
- 0:55what the heck is raycasting and how can
- 0:57we use raycasting inside of our scripts
- 1:00to make really cool systems. So I have
- 1:02this little visual example here and to
- 1:04give you a fundamental definition of
- 1:07what ray casting is, it's the process of
- 1:10sending out an invisible line from a
- 1:13starting point in a specific direction
- 1:16with a defined length. So to help you
- 1:19understand what I'm talking about here,
- 1:20we have this red line here that's going
- 1:22to represent our ray. And we have this
- 1:25blue part here that represents our
- 1:26starting point of this line. And so if
- 1:29we were to take this line and we start
- 1:31it over here, then what we're going to
- 1:34do is we're going to use ray casting to
- 1:37essentially shoot a ray in a specific
- 1:39direction with a defined length. and
- 1:41it's going to try and detect if there's
- 1:44an object that intersects with that
- 1:47line. So, in other words, when we shoot
- 1:50this ray, we cast the ray to the world,
- 1:53hence the name ray casting, and it's
- 1:55just going to shoot a line like this,
- 1:56and it's going to try and detect an
- 1:58object that's in the way of it. And if
- 2:00it does detect an object, then we're
- 2:02going to get information about that
- 2:04object in specific to then do stuff with
- 2:07our scripts. So, it seems pretty cool
- 2:10and all, but how does this actually help
- 2:12us as Roblox developers? Well, let's say
- 2:14for instance, we have a system like uh a
- 2:17turret where if a player walks in front
- 2:19of the turret, then we want to get
- 2:20information about whether this is a
- 2:22player that's standing in front of the
- 2:23turret. And if it is a player, then we
- 2:26want to start firing the turret in this
- 2:28direction. Or let's say we have a gun
- 2:30system where if we shoot in a specific
- 2:33direction, then we want to use ray
- 2:36casting to fire a bullet from the gun to
- 2:39where the player clicked on their mouse.
- 2:41Let's say another use case is if we want
- 2:43to have a placement system where we want
- 2:46to get the player's mouse and we want to
- 2:48locate it with respect to the game's
- 2:50world to be able to place down items
- 2:52inside of the game. That also uses ray
- 2:54casting. There's even things like weapon
- 2:56hit detection. So, if you have like a
- 2:58sword and you want to be able to detect
- 2:59if a player is being hit by your sword's
- 3:02hitbox, then that's another practical
- 3:04use case of raycasting. And it's, as I
- 3:06mentioned before, the list just goes on
- 3:07with ray casting. It's a very widely
- 3:09used concept in Roblox scripting, but it
- 3:11can be challenging to those who have
- 3:13never used raycasting before. And my
- 3:16goal for this video is to teach you the
- 3:18fundamentals of raycasting and how you
- 3:20can use raycasting in your scripts to
- 3:22make really cool systems like this. So
- 3:24with that being said, let's go ahead and
- 3:26go straight into implementing ray
- 3:28casting. Now that we understand it,
- 3:30let's implement ray casting inside
- 3:32Roblox Studio. Now it's as I said
- 3:34earlier in this episode, in order to
- 3:35perform ray casting, we need two pieces
- 3:38of information. One is the starting
- 3:40point, also known as the origin, and the
- 3:42other is the direction that we want to
- 3:45take from that starting point. And an
- 3:47easy way that we can do this is by using
- 3:49a part as the starting point. And then
- 3:52we specify our own direction based off
- 3:54of that starting point. So what we're
- 3:56going to do is go into model and we're
- 3:58going to insert a part. Now with this
- 4:00part, I'm going to scale down just a
- 4:01little bit. I'm going to change the
- 4:03brick color to something different. I'm
- 4:04going to set anchored to true. And I'm
- 4:07also going to rename this part to origin
- 4:10part just like this. Now what we're
- 4:12going to do is go inside of server
- 4:13script service, hit the plus sign, and
- 4:15we're going to insert a script. Now from
- 4:17here we're going to first make reference
- 4:19to our origin part by saying local
- 4:21origin part equals workspace.org part
- 4:24just like this. Now we need to specify a
- 4:27direction. Now this direction can be any
- 4:29vector 3 value that we pick. But let's
- 4:31say from the origin point we want the
- 4:35ray to be 100 studs going this way. So
- 4:39if we were to specify the direction by
- 4:41saying local direction equals vector 3.
- 4:45Uh then what we're going to do is put
- 4:47100 for the X and then zero for the Y
- 4:50and then zero for the Z. So when we
- 4:53combine our origin part with its
- 4:55direction, the ray is going to look
- 4:57something like this where this is the
- 4:59starting point and then it goes 100
- 5:00studs this way. So this is what the ray
- 5:03is going to look like when we cast it
- 5:04into the world. Okay. So now that we
- 5:07have our pieces of information, how do
- 5:09we actually cast the ray into the world?
- 5:11Well, we can do this using the
- 5:13workspaces raycast method and we're
- 5:15going to be doing that under a loop by
- 5:17either using a while loop or by using
- 5:19run service. But in this case, we're
- 5:20going to use run service. So at the top
- 5:22here, we're going to make reference to
- 5:24run service by saying local run service
- 5:26equals game get service run service just
- 5:30like this. Now down here we're going to
- 5:32say run service heartbeat colon connect
- 5:36function open close parenthesis enter.
- 5:38Now we're going to use that raycast
- 5:39method that I mentioned before. So, what
- 5:41we're going to do is say workspace colon
- 5:45raycast open and close parenthesis. And
- 5:47this takes in three pieces of
- 5:49information, but right now we're going
- 5:50to be focused on the first two, which is
- 5:52the origin. So, we're going to say
- 5:54origin part.position.
- 5:56And then we're going to throw in the
- 5:58direction as well. So, this casts our
- 6:01array into the world. And this is going
- 6:04to return what's called a raycast result
- 6:07that gives us information about the
- 6:09object that this ray has hit. So we're
- 6:12going to throw this inside of a uh
- 6:14variable by saying local ray result
- 6:17equals and then the workspace raycast
- 6:19method here. So from here we're going to
- 6:22say if ray result then this is basically
- 6:25going to tell us that there was an
- 6:26object that actually hit the ray. So,
- 6:28we're going to say something like
- 6:30something has hit the array. Uh,
- 6:34otherwise, we're just going to say
- 6:36nothing has hit the array or something
- 6:39like that just to tell us information
- 6:41about whether there is an object that
- 6:43was actually in the way of the ray or
- 6:44not. Okay. So, in order for us to tell
- 6:47whether this is actually working, let's
- 6:49insert another part here. I'm just going
- 6:51to make this like a big wall just like
- 6:53this. And what we're going to do is go
- 6:55to test and hit run. And basically
- 6:59inside the output it's going to say that
- 7:01nothing has hit the ray multiple times.
- 7:04So right now the ray looks something
- 7:05like this. And if we were to move this
- 7:08object in the way of the ray then as you
- 7:11can see in the output it says something
- 7:13has hit the ray. And if we move the wall
- 7:15away again then it's going to say
- 7:17nothing has hit the ray. So this is the
- 7:19basic idea behind ray casting. It's to
- 7:22shoot array into the world and it's to
- 7:24give us information about objects that
- 7:27intersect that array. That's the whole
- 7:29idea behind it. Now, you might be
- 7:31wondering what information does this
- 7:33raycast actually return. Well, if we go
- 7:35back into our script and let's say that
- 7:37ray result was successful and we say ray
- 7:39result dot, we can see that there's five
- 7:42pieces of information that ray result
- 7:44does provide to us. The first one is the
- 7:46instance which basically tells us what
- 7:48was the instance that hit the ray. The
- 7:51second one is the exact position as to
- 7:54where the ray and the part hit each
- 7:57other. Uh the third thing is the
- 7:58material of the object that the ray hit.
- 8:01And then we have a normal vector and we
- 8:03also have a distance which tells us how
- 8:06far apart was the ray origin and the
- 8:08point at which both the ray and the
- 8:11object hit. So depending on what you're
- 8:12creating, these pieces of information
- 8:14can be really helpful in terms of what
- 8:16you want to accomplish with ray casting.
- 8:18Okay. So before we move on, I want to
- 8:20help you visualize these rays that we're
- 8:22creating by using a function that
- 8:24basically shows us what these rays look
- 8:26like so that we're not working with
- 8:28invisible rays throughout this entire
- 8:29episode. And so basically what I did was
- 8:31I created this function here called
- 8:33visualize ray that takes in two
- 8:35parameters. One is the origin and the
- 8:37other is the direction. So if we open
- 8:38this up, basically what's happening here
- 8:40is we're creating a new part. We're
- 8:42setting some properties and we're
- 8:43setting the parent of this to workspace
- 8:45and we're using debris to automatically
- 8:47get rid of this part after 0.5 seconds.
- 8:50Now what we need to do to complete this
- 8:52function is by defining some variables
- 8:54and by changing the size and the C frame
- 8:56of this part to accurately reflect on
- 8:59what the rays will look like and where
- 9:01it's placed. So we need two pieces of
- 9:03information which I'm going to explain
- 9:04what these are in just a little bit. But
- 9:06we need to define the length and the
- 9:08midpoint. So what we're going to do is
- 9:09say local length equals direction
- 9:13domagnitude
- 9:15just like this. And then we're going to
- 9:17define the midpoint by saying local
- 9:19midpoint equals origin plus direction*
- 9:240.5. So length is what's used to tell us
- 9:28how big we want this laser to be. And
- 9:32then midpoint is what's going to tell us
- 9:34where we want to position this ray that
- 9:37we create. Now the reason we want
- 9:39midpoint rather than let's say starting
- 9:41this laser at where the origin is is
- 9:44let's say we had a laser that looked
- 9:46like this. So we positioned this laser
- 9:48to be where the origin is. But if we
- 9:50were to change the size of this to make
- 9:52it look like this, then obviously this
- 9:54isn't where we want the laser to be.
- 9:57Instead, we want the laser to be like
- 9:59this instead because this reflects our
- 10:02ray more accurately than what I was
- 10:03showing you just a second ago. And in
- 10:05order for us to get this accurate
- 10:07position, we need to take the origin and
- 10:11the direction. So this is the origin and
- 10:13this is the direction. And we want to
- 10:14get half of that which is in the center
- 10:17here. This is the midpoint and this is
- 10:19the the the exact position that we want
- 10:21when we're trying to cast this ray into
- 10:23the world and by visually showing this
- 10:26as well. So that's what I'm trying to
- 10:28show with both the length and the
- 10:29midpoint. And now we can change the size
- 10:31in the C frame with these pieces of
- 10:33information. So what we're going to do
- 10:34is say new part do size equals vector 3
- 10:39new. We can set X and Y to be a really
- 10:41small number like 0.1 and 0.1. And then
- 10:45for Z, we're just simply going to throw
- 10:47in the length just like this. And now
- 10:49what we're going to do is say new part.
- 10:50Cframe equals Cframe new. And then
- 10:54inside of here, we're going to start it
- 10:57at the midpoint. So it's going to start
- 11:00right here in the center. And for the
- 11:03look vector, we're going to say origin
- 11:06plus direction just like this. And this
- 11:08is all that we need to do for our
- 11:10visualize ray function. So now what we
- 11:12can do down here is inside of our
- 11:14heartbeat loop. As soon as we get the
- 11:16ray result, we're going to say visualize
- 11:18ray and then we're going to pass in the
- 11:20origin part.position and then we're
- 11:22going to throw in the direction just
- 11:24like this. And this is our visualize ray
- 11:26function that's going to be helpful for
- 11:28us. So if we go into the game, I'm just
- 11:30going to delete this origin part. And if
- 11:32we hit run, then what we should see is
- 11:34now we have a visual array that we can
- 11:36look at to really see what is actually
- 11:39happening inside the workspace. So, if I
- 11:41were to move this part in front of the
- 11:43ray, then what it's going to do is it's
- 11:45going to say that something has hit the
- 11:46ray. And if we lift it back out, then
- 11:48it's going to say nothing has hit the
- 11:49ray. And so, this is what we're going to
- 11:51be using for the rest of this episode to
- 11:52really help us visualize what these
- 11:54lasers are going to look like. Okay. So,
- 11:56right now, we have a one-part raycast
- 11:59system where we have a part that acts as
- 12:02the origin point and then we have a
- 12:04direction that tells us how far do we
- 12:07want this ray to shoot out. So, it looks
- 12:09something like this currently. And we
- 12:10can move this starting point around to
- 12:13adjust where the ray is inside the
- 12:15world. But what if we wanted to create a
- 12:17two-part system where we have a starting
- 12:20point that's going to be a part and then
- 12:22we have an ending point or a goal that's
- 12:24also going to act as a part. So it's a
- 12:27two-way system where if we change the
- 12:28goal or the starting point, then it's
- 12:30going to affect how the raycast is
- 12:34displayed in the world. We can do that
- 12:35really quickly if we hit stop. And what
- 12:37I'm going to do is duplicate this origin
- 12:39part, move it over here. Uh I'm going to
- 12:41rename this to goal part. And I'm going
- 12:45to change the brick color this to
- 12:46something like yellow. So if we go
- 12:47inside of our script, what we're going
- 12:49to do is first make reference to the
- 12:51goal part by saying local goalpart
- 12:54equals workspace.galpart.
- 12:56And then what we're going to do here is
- 12:58we need to specify the direction based
- 13:01off of the goal parts position and the
- 13:03origin parts position. So, I'm going to
- 13:05comment out this direction definition up
- 13:08here, and I'm going to move it down here
- 13:10by saying local direction equals
- 13:13goalpart.position
- 13:15minus origin part.position. And then
- 13:18we're going to use this new direction to
- 13:20define our ray inside of the world. So
- 13:24if we now hit run, then what's going to
- 13:26happen is we're going to use ray casting
- 13:29to shoot array from the origin point and
- 13:32to the destination as well. And if we
- 13:35were to change either of these parts,
- 13:37then as you can see, the raycast is
- 13:39being updated to reflect on these new
- 13:42positional changes either on the goal or
- 13:45at the origin. So, this is pretty cool
- 13:47if you know the destination plus the
- 13:50origin so that you can create raycasts
- 13:52into the world that reflect on both of
- 13:55these parts just like this. Now, you
- 13:58might notice something. It says down
- 13:59here in the output that something has
- 14:01hit the ray and it keeps displaying this
- 14:03for some reason. There isn't anything
- 14:05blocking it. So, what's the problem
- 14:07here? Well, the problem here lies in how
- 14:10we specified that any object whatsoever,
- 14:14it doesn't matter what object it is, it
- 14:16is going to detect anything that's in
- 14:18the way of this ray. And what is this
- 14:20part? Well, the part that this ray is
- 14:23intersecting is this goal part right
- 14:25here. But what if we don't want this
- 14:27goal part to be part of the raycast
- 14:31detection? Well, this is a perfect
- 14:32transition into what we're going to be
- 14:34talking about next, which is called
- 14:35raycast parameters. So, raycasting has
- 14:38this cool feature that allows us to
- 14:40choose which specific instances can
- 14:43either be included or not be included in
- 14:46the list of instances that can be
- 14:49intersected with the rays that we shoot
- 14:52into the world. So, how this can be
- 14:54useful is with the example I just
- 14:56explained earlier and how we have a
- 14:58starting point, which is this part right
- 14:59here. So, we shoot the ray starting from
- 15:01here and then it goes into the goal
- 15:03part. But on the output, it's been
- 15:04saying that something has hit the ray
- 15:06even though nothing is actually in
- 15:08between these two points. And that's
- 15:10because it's detecting this goal part
- 15:12right here, which we don't want to
- 15:13include in the list. So, in order to
- 15:16handle situations like this, we're going
- 15:18to create what are called raycast
- 15:20parameters and add this goal part to the
- 15:24list of instances that are not allowed
- 15:26to be intersected with the ray. So let's
- 15:29go to our script so that we can make
- 15:31this change. And what we're going to do
- 15:33is create raycast parameters by saying
- 15:36local raycast params equals raycast
- 15:40params new open and close parenthesis.
- 15:43And now inside of here we're going to
- 15:45say raycast params dot filter descendant
- 15:50instances equals open and closed curly
- 15:53braces. And this is the table of all the
- 15:56instances that we don't want to include
- 15:58in the list or instances that we do want
- 16:00to include. So in this case, we're going
- 16:03to say goalpart here as the only
- 16:05instance in the list. And then we're
- 16:06going to say raycast params dot filter
- 16:10type equals enum dot
- 16:14raycast filter type dot. And then we
- 16:16have two options with either excluding
- 16:18or including whatever is inside of this
- 16:20list. But for this example, we're going
- 16:22to say exclude because we don't want to
- 16:25include this goal part as one of the
- 16:27instances that can be detected by this
- 16:29array. And finally, what we're going to
- 16:31do is we're going to throw in a third
- 16:33argument inside of our raycast method.
- 16:37And we're just simply going to pass in
- 16:38the raycast params just like that. So
- 16:42now if we go into the game and hit run,
- 16:44what we should see in the output is now
- 16:46nothing is hitting the ray, even though
- 16:49it technically is hitting this goal
- 16:51part, but we chose to ignore this goal
- 16:54part with this ray that's being fired.
- 16:56And if we move the wall over to here,
- 16:58then it's going to say that something
- 16:59has hit the ray, just like so. And if I
- 17:02lift it back out, then it's going to say
- 17:03that nothing is hitting the ray again.
- 17:04So raycast parameters are very useful if
- 17:07we don't want specific instances to be
- 17:09intersected with the rays or if we want
- 17:12only a specific number of instances to
- 17:15be intersected with the rays and we just
- 17:17ignore everything else. Okay, so with
- 17:19what we know, let's create a gun system
- 17:22using ray casting. And I want you to
- 17:24follow exactly what I do as we create
- 17:26the system. And the first thing we need
- 17:27to do is create the gun itself. So what
- 17:30we're going to do is go to model and
- 17:31we're going to hit part. Now, with this
- 17:33part, I'm going to scale it down just
- 17:34like this. Scale it up like this. And
- 17:37I'm going to rename this part to handle.
- 17:40And I'm going to go down here and turn
- 17:42off can collide. Then I'm going to hit
- 17:44the plus sign inside of workspace,
- 17:46insert a tool. I'm going to rename this
- 17:48tool to gun. And I'm going to put the
- 17:50handle inside of this gun, just like
- 17:52this. Next thing I'm going to do is
- 17:54duplicate the handle, scale it down, and
- 17:56move it to the right like this. And I'm
- 17:59going to rename this to part. And then
- 18:01I'm going to duplicate it one more time,
- 18:02move it over here, and call this the
- 18:05point, which is going to be where our
- 18:07bullets are going to be fired from. So
- 18:09to indicate this, I'm just going to
- 18:10change the brick color to, let's say,
- 18:12black. And now we have our gun. But we
- 18:14need to attach all these parts together
- 18:16so that they don't fly off when we u
- 18:18actually use it in the game. So we're
- 18:20going to use weld constraints by hitting
- 18:21the plus sign inside a part, inserting a
- 18:23weld constraint. We're going to set part
- 18:26zero to the part and then part one to
- 18:29the handle. And then I'm going to copy
- 18:30this weld constraint, put it inside a
- 18:32point, and I'm going to change part zero
- 18:34to be the point instead. And now
- 18:36everything should be connected together.
- 18:38But I want you to be careful because
- 18:40depending on how you design this, when
- 18:42you hold the gun, it's probably not
- 18:43going to be oriented correctly. And I'm
- 18:45going to show you a neat trick that you
- 18:47can use to check to see if you're facing
- 18:50the model correctly based on how you're
- 18:52designing it. So, with this handle, what
- 18:54we're going to do is we're going to
- 18:55right click on this handle, and there
- 18:57should be this option called show
- 18:58orientation indicator. And there's this
- 19:01little arrow here that shows you where
- 19:03the front-facing side of the handle is.
- 19:06And so, now all we need to do is just
- 19:08move these parts over here so that we
- 19:10can orient them correctly, just like
- 19:13this. So, I'm just going to right click
- 19:14on this and then hide orientation
- 19:16indicator. And if we now move the gun to
- 19:18starter pack and if we hit test and hit
- 19:21play, then what we should see is when we
- 19:24use our gun, then it should be oriented
- 19:27correctly. And now we have a gun for the
- 19:30player to use. So that's how you create
- 19:32the gun. And now we need to create the
- 19:34functionality of the gun. So we need
- 19:36three things with this gun. And before I
- 19:38do, I'm just going to take the part and
- 19:39the point and put it inside the handle
- 19:41just to make it more organized. So we
- 19:43need three things. We're going to hit
- 19:44the plus sign inside of gun. We're going
- 19:46to insert a script. We're going to
- 19:48insert a local script. And we're going
- 19:50to insert a remote event. So, with all
- 19:54of these three things, what we need to
- 19:56do essentially is make it so that when
- 19:58the player clicks their mouse on a
- 20:00specific direction, then we want to send
- 20:02that information to the server so that
- 20:04we can create a ray that will shoot out
- 20:07from the point of the gun to the
- 20:11direction of where the mouse is. And
- 20:12that's the whole idea behind this gun.
- 20:14uh while we use raycasting. So I'm going
- 20:16to rename this remote event to fire gun.
- 20:19And inside of our local script, we're
- 20:21going to make reference to the tool by
- 20:23saying local tool equals script.parent.
- 20:25Then we're going to say local fire gun
- 20:28equals tool colon waitfor gun just like
- 20:32this. And what I'm also going to do is
- 20:34say local player equals
- 20:37game.players.local
- 20:38player. And then we're going to get the
- 20:40player's mouse. So, we're going to say
- 20:42local mouse equals player colon get
- 20:46mouse open and close parenthesis just
- 20:48like this. And now what we're going to
- 20:49do is say tool.activated
- 20:52col connect function open close
- 20:54parenthesis enter. We're simply just
- 20:55going to say fire gun colon fire server
- 20:59open close parenthesis. And there's two
- 21:01pieces of information that we need. So
- 21:03we need the origin point and we also
- 21:06need the direction which we specified
- 21:08before with raycasting. And basically
- 21:10what we need is the point part. So we're
- 21:12going to say local point part equals
- 21:15tool colon wait for child handle colon
- 21:18wait for child point just like this. So
- 21:22we're going to say point part.position.
- 21:25This is going to be our origin. And then
- 21:26we're going to say mouse.h hit.position
- 21:30which is basically the position of where
- 21:32the player fired their mouse. So now
- 21:35we're done with the local script. So, if
- 21:36we go into our normal script, I'm just
- 21:39going to copy the tool reference and
- 21:41just put it inside of here. What we're
- 21:42also going to do is make reference to
- 21:44the fire gun remote event by saying
- 21:46local fire gun equals tool. Fire gun
- 21:49just like this. Then we're going to say
- 21:51fire gun onserver event connect function
- 21:55open close parenthesis. So, there's
- 21:56three pieces of information here.
- 21:58There's the player, there's the origin,
- 22:02and then there's the mouse position. So
- 22:05with these three pieces of information
- 22:06we can now start creating raycasts on
- 22:09the server side. So the first thing that
- 22:11we need to do is calculate the direction
- 22:13which is basically let's imagine that
- 22:16this is the origin point like this is
- 22:17the point part and we want to make it so
- 22:20that we get the direction from where the
- 22:24mouse position was versus where the
- 22:27origin point was which is always going
- 22:28to be the point part. So if we were to
- 22:32let's say calculate it, it would look
- 22:34something like this. This is the result
- 22:36that we're trying to get. And the way we
- 22:38can do this is we just simply uh
- 22:40subtract the mouse position with the
- 22:42origin position, get a unit vector of it
- 22:44so that it looks something like this,
- 22:45and then multiply it by some sort of
- 22:47scaler, which shows us how far we can
- 22:49shoot the gun, which let's say in this
- 22:51case is 50 studs. It's going to look
- 22:53something like that. So we want to be
- 22:54able to calculate that inside of our
- 22:56script. So if we go back to our script,
- 22:58we can say local direction equals open
- 23:01close parenthesis mouse position minus
- 23:05origin dot unit times and then we can
- 23:09say however many studs we want. We can
- 23:12say 50. Now that I think about it, we
- 23:14can actually just create a uh variable
- 23:16here by saying local distance multiplier
- 23:20just like this. And then we can say
- 23:21something like 50 just so that we can
- 23:23make it adjustable later if we want to.
- 23:26So, now that we have that, we can go to
- 23:28our original script that we used earlier
- 23:31in this tutorial guide and we can just
- 23:32copy the same raycast parameters here
- 23:34because when we're going to be firing
- 23:36our gun, there are certain things that
- 23:37we don't want to intersect with the ray.
- 23:40So, we're going to go to our original
- 23:41script, copy this, and then paste it
- 23:43inside of here. Now, for the filter
- 23:45instances, what we can do is create a
- 23:47variable here called local excluded
- 23:51parts equals open and close parenthesis.
- 23:53And then we can just replace that with
- 23:55this. And now what we're going to do is
- 23:58we're going to use the raycast method by
- 24:01saying local ray result equals workspace
- 24:04colon raycast. And then we're going to
- 24:06throw in the origin the direction and
- 24:10then the raycast params just like that.
- 24:13And we're going to check if the result
- 24:15was successful. So we're going to say if
- 24:17ray result then we're going to say we
- 24:20have found something. So, result has
- 24:22been found. And then we're just going to
- 24:24print the ray result for testing
- 24:25reasons.
- 24:27And then what we're going to do is we're
- 24:29going to go back to our original script
- 24:31and we're literally going to copy the
- 24:32exact same visualize ray function and
- 24:35we're just going to paste it inside of
- 24:37here. Just like this. Except one thing
- 24:39we can do is probably change the color
- 24:40of this to let's say orange. And what
- 24:43we're going to do here is we're going to
- 24:44say visualize ray origin direction. Just
- 24:48like that. So what do we want this ray
- 24:51to actually do? Well, we can do a couple
- 24:53things. Uh, one thing is we can change
- 24:55the color of the instance that the
- 24:57bullet has hit to a different color. So
- 24:59what we can do is say ray results do
- 25:02instance.color
- 25:04equals color3.RGB.
- 25:07And then we can change this to orange.
- 25:10And if this ray was not successful, then
- 25:12what we're going to do is we're just
- 25:14simply going to say result not found.
- 25:18And then we can do the same thing with
- 25:20the visualize ray function. We're just
- 25:22going to put that here as well. Okay. So
- 25:24now if we go into the game, hit test,
- 25:28and hit play, then what we should see
- 25:30with this gun is if we were to fire it
- 25:33at a certain direction, then it's going
- 25:35to shoot a ray from the origin point,
- 25:38and then it's going to fire off in the
- 25:40direction of the player's mouse. And
- 25:42it's going to tell us if a result has
- 25:44been found or if a result has not been
- 25:46found. So if we were to shoot this wall,
- 25:48then it did find an instance and it
- 25:51changed the color of that instance to
- 25:53the color that we specified inside of
- 25:54the script. And we can do this with
- 25:56basically any instance that this has
- 25:58detected. And so that is uh something
- 26:01that we can do with this gun. But let's
- 26:03add another functionality. Let's make it
- 26:05so that if this gun detects a player,
- 26:08then we want that player to take damage.
- 26:10And we can do that inside of here by
- 26:12first locating the character. So we're
- 26:13going to say local character equals
- 26:15array result.instance
- 26:18colon find first ancestor of class open
- 26:23and close parentheses model. And the
- 26:24reason we say it like this is because a
- 26:26player's character is a model. And if we
- 26:29find the first ancestor of a specific
- 26:32instance, which is likely going to be
- 26:33the player's body part, like its arm or
- 26:36its torso or anything like that, then
- 26:39we're going to see if this is an actual
- 26:40character based off of that information.
- 26:43So then if we do find the character then
- 26:45we're going to try to find the humanoid.
- 26:47So we're going to say local humanoid
- 26:48equals character find first child of
- 26:51class and then we're going to say
- 26:52humanoid. So if the humanoid does exist
- 26:55then we're just simply going to say
- 26:56humanoid colon take damage and then
- 27:00we're going to specify like a damage
- 27:02amount like five or something. We can
- 27:04even set that here as well. So local
- 27:07damage equals five. And then we can just
- 27:09replace that with this damage. And I
- 27:12meant to say humanoid here. Okay. So now
- 27:15we can test this even further. If we go
- 27:17to avatar and we click on rig builder,
- 27:19we could just select any rig. I'm just
- 27:22going to say block avatar. And if we now
- 27:24go into test and hit play, then we can
- 27:27test out this gun by firing it at the
- 27:29NPC. And as you can see, it's taking
- 27:31five bits of damage every single time.
- 27:33And that's the result that we wanted to
- 27:35achieve from this. Now, this is a
- 27:37simplified way of creating a gun system
- 27:39using ray casting. But I hope you've
- 27:41been able to learn something from using
- 27:43ray casting to create this gun system
- 27:45that we just created. Okay, so one thing
- 27:47I forgot to do was add to our excluded
- 27:50parts table. Now you might be wondering
- 27:52what should we add to the excluded parts
- 27:54table? Well, there's two important
- 27:56things. So what we're going to do is say
- 27:57table.insert
- 27:59and then for excluded parts, we're going
- 28:01to include the player.c character. And
- 28:03the reason we want to do this is because
- 28:05we don't want to make sure that we hurt
- 28:07ourselves when we fire the ray. And also
- 28:09another thing is over here in our
- 28:11visualize array function, we want to
- 28:14make sure that we add the ray itself
- 28:18into the excluded parts because we don't
- 28:20want the part to be able to interact
- 28:21with each other when we shoot multiple
- 28:24rays at the same time. So we're just
- 28:26going to copy the same uh thing here and
- 28:29paste inside of here, but instead we're
- 28:31just going to add new part instead to
- 28:34our visualize rate function. So, I
- 28:36wanted to clear that up to make this gun
- 28:38system even better that actually uses
- 28:39the raycast parameters. Hey, post edit
- 28:42broad here. So, it turns out there's
- 28:44actually a few mistakes that I made with
- 28:46the raycasting gun script that we just
- 28:48created. And I just wanted to quickly
- 28:50address what these problems are and how
- 28:52we can create a fixed version for this
- 28:54because the script that we have right
- 28:55now technically works, but there are a
- 28:58few issues with it that can make this
- 29:01problematic. And so, I just want to
- 29:02quickly address them. So if we go inside
- 29:04of our scripts, there are two problems
- 29:06here. Uh one is we're using excluded
- 29:09parts as a global table which can
- 29:11actually cause memory leaks based on the
- 29:13way that we've implemented this. And
- 29:15another problem is if we scroll down
- 29:17here, we can see that raycast is being
- 29:20fired before the visualize ray method.
- 29:23Now you might be thinking why is this a
- 29:25problem? Well, if we go inside of the
- 29:27visualize array method over here, uh
- 29:30we're using table.insert insert to
- 29:32insert this new array that we shoot and
- 29:34put it inside of the excluded parts
- 29:36table. Now, the reason we do this is
- 29:38because we want to add all of these rays
- 29:41as filters for raycast parameters so
- 29:44that when we fire the bullets, the other
- 29:47visualized bullets are not going to be
- 29:48included with the ray casting, which is
- 29:50the whole point behind this. But if you
- 29:52still don't see the problem, basically
- 29:55when we fire raycast, we want to take
- 29:58into consideration all the excluded
- 30:00parts that are in here. But if we're
- 30:02adding these new parts to excluded parts
- 30:05after the raycast has already been
- 30:08fired, then there's no point of doing it
- 30:11because the raycast method has already
- 30:13been fired. So we actually need to fire
- 30:15visualize ray before the raycast method
- 30:18over here. So those are some issues that
- 30:20we need to change. And one thing that I
- 30:22want to mention with the whole memory
- 30:24leakage thing is when we use debris to
- 30:27get rid of these new parts, the
- 30:29references to these parts inside of
- 30:32excluded parts are still inside the
- 30:35table, which is why it can accumulate
- 30:37over time and create a memory leakage.
- 30:39So if I were to show you what I'm
- 30:41talking about, I'm just going to write a
- 30:42print statement and I'm going to print
- 30:44the number of items that are inside of
- 30:46excluded parts. So if I fire with my
- 30:48gun, then as you can see in the output,
- 30:50the number that's being displayed is the
- 30:53number of entries that are inside of
- 30:55excluded parts. And as you can see, it's
- 30:57not going away because the rays
- 30:59disappear, but the references to those
- 31:01rays inside of excluded parts are still
- 31:04inside the table. And if we keep firing
- 31:06this, then this is just going to
- 31:07accumulate more and more over time,
- 31:09which is not good. Which is why we need
- 31:11to fix this as one of the problems. And
- 31:13I hope that this part is making sense so
- 31:15far. Okay, so I created a fixed version
- 31:18of the gun ray casting script. Um, so if
- 31:20we go inside of here, then uh I I
- 31:23basically commented out all the parts
- 31:24that we don't need anymore. So this
- 31:26global reference to excluded parts is no
- 31:29longer here because we moved it down
- 31:32here every single time the player fires
- 31:35the gun. So we create a new excluded
- 31:38parts table every single time. And
- 31:40another thing that I changed was this
- 31:42visualize array function is now being
- 31:44fired before the raycast uh method. So
- 31:48if we go inside of visualize array, the
- 31:51things that I've changed here are a few
- 31:53things. So instead of setting the parent
- 31:55of the bullet inside of workspace, we're
- 31:57instead putting it inside of what's
- 31:59called a visualization folder. So this
- 32:01is a little folder that I created called
- 32:03bullet visuals and it's stored inside of
- 32:05the workspace. So, it's basically this
- 32:08bullet visuals folder right here. So, if
- 32:10I were to fire my gun, then all the
- 32:13bullets are being stored inside of this
- 32:15one folder. And the reason it's like
- 32:17this is because this makes it a lot
- 32:19easier for us to keep track of all the
- 32:21bullets that are going to be included in
- 32:24the raycast parameters so that we don't
- 32:27include them when we're firing the
- 32:29bullets uh inside the game. So, we also
- 32:32got rid of the debris method and instead
- 32:35what we're going to do is simply return
- 32:37the new part and and have it be a
- 32:40variable here called visual part so that
- 32:42we can use it inside of this part of the
- 32:45script. So, with excluded parts, we want
- 32:48to include the player's character and we
- 32:49want to also include everything that's
- 32:52inside the visualization folder with all
- 32:54the bullets. So, another thing is I also
- 32:56got rid of all the visualize array
- 32:58methods over here. And I also completely
- 33:01got rid of this else uh branch in this
- 33:04if statement right here because we don't
- 33:06really need it. And at the very end
- 33:08here, I added the game debris add item
- 33:11method and I just got rid of the visual
- 33:14part after 0.5 seconds. So, this is
- 33:17basically how we create a more robust
- 33:20raycast gun script that not only
- 33:24prevents memory leaks from happening
- 33:26because we're creating an excluded parts
- 33:28table every single time the player fires
- 33:31the gun instead of having it be global,
- 33:33but also this is a more appropriate way
- 33:36of using raycast parameters because now
- 33:39this raycast is actually taking into
- 33:41consideration the new bullet visual that
- 33:44has been created inside the game before
- 33:47we fire the raycast method. So, I just
- 33:50wanted to quickly address this because
- 33:52if I left the current script as is, then
- 33:54you probably would have been misusing
- 33:56the raycast methods inside of this video
- 33:59and I did not want that. So, I just
- 34:01wanted to quickly address it. And if you
- 34:03still are watching up until this point,
- 34:05then I really appreciate it a lot. I do
- 34:07put in a lot of time into the scripting
- 34:09tutorials, and there's not that much
- 34:11left on this episode. So, I want you to
- 34:13keep in mind as you follow through the
- 34:15rest of this video is that I'm still
- 34:16going to be misusing the raycast
- 34:18parameters. So, I just want you to keep
- 34:20an open mind as you follow through the
- 34:22rest of this episode. That is all for
- 34:24me. Thank you so much. Now, you might be
- 34:26asking yourself, is it possible to
- 34:29change the shape or the size of these
- 34:31rays? Because theoretically, ray casting
- 34:34is when you shoot a very tiny thin
- 34:37invisible ray uh inside the world. But
- 34:40if we wanted to utilize the
- 34:41functionality of ray casting, but
- 34:43instead using different shapes and
- 34:46different sizes, then it actually is
- 34:48possible. We can use things like block
- 34:51casting, shape casting, and sphere
- 34:53casting that can make bullets that look
- 34:55something like this. So we can use
- 34:58things like cylinders with different
- 34:59sizes. And we can even use things like
- 35:01blocks to achieve the same effect, but
- 35:04instead have like a bigger volume. So
- 35:07that's the definition of these shape
- 35:09casts and block casts and things like
- 35:11that. It's basically ray casting, but if
- 35:14it had volume. And so I think this is
- 35:16something really important to understand
- 35:18when you're utilizing this inside of
- 35:19your Roblox games. And we're just simply
- 35:21going to take our existing gun script
- 35:23and we're just going to modify it to use
- 35:26these casts instead of ray casting. So
- 35:29let's go ahead and go do that right now.
- 35:30Okay. So, we're going to modify our
- 35:32current gun system to use sphere casting
- 35:35to increase the size of our bullets. And
- 35:38basically what we're going to do is
- 35:39we're going to go to our script and
- 35:41inside of our remote event, we're just
- 35:44going to change two things. The first
- 35:45thing is instead of firing raycast,
- 35:48we're going to fire sphere cast instead.
- 35:51And this takes in four parameters
- 35:53instead of three. So we still have the
- 35:55origin, the direction, and the raycast
- 35:57parameters, but as part of the second
- 35:59parameter, this is taking what's called
- 36:01a radius, which determines the radius of
- 36:05the spherical shape in studs. So we can
- 36:08set this to be a number like two. But we
- 36:10can also just create a variable up here
- 36:11by saying local bullet uh radius equals
- 36:162. And then we can just replace this two
- 36:18with the variable we just created. Next
- 36:20thing we're going to change is instead
- 36:21of visualize ray, we're going to create
- 36:23our own function for visualizing the
- 36:26shape because we're not visualizing
- 36:28array anymore. We're visualizing a
- 36:29shape. So we're going to create a new
- 36:32function up here by saying local
- 36:34function visualize shape and then it's
- 36:37going to take in the origin, the
- 36:39direction, but this is also going to
- 36:41take the ray result as well. And this is
- 36:44what we're going to be calling instead.
- 36:46So, we're going to say visualize shape
- 36:49origin direction and then the ray
- 36:52results just like that. And I'm also
- 36:54going to copy that and paste it down
- 36:56here as well. Okay. So, here's how this
- 36:59is going to work. We're going to create
- 37:01a visual bullet inside of Studio and
- 37:04we're going to clone that bullet and
- 37:06shape it so that it's going to match
- 37:08where the player is going to be firing.
- 37:10And we're also going to adjust the size
- 37:11of it as well. So, what we're going to
- 37:13do is go to model, hit part, and we're
- 37:15going to create a cylinder, and we're
- 37:18going to rename this to bullet, and then
- 37:22we're going to change the brick color of
- 37:23this to, let's say, orange. And we're
- 37:25going to change the material of this to,
- 37:27let's say, neon. I'm going to set can
- 37:31collide off, and I'm going to turn on
- 37:33anchored, just like this. Okay. So now
- 37:36that we have this bullet, I'm going to
- 37:37throw this inside of server storage. And
- 37:39we're going to make reference to this
- 37:41bullet inside of our script by saying
- 37:44local bullet equals game.server storage
- 37:48dot bullet. Just like that. So now what
- 37:51we're going to do inside of visualize
- 37:53shape is we're just simply going to
- 37:55clone the bullet. So we're going to say
- 37:57local new bullet equals bullet
- 38:02colon clone. And then we're going to set
- 38:05the parent of this new bullet. So new
- 38:06bullet.parent equals workspace. And then
- 38:08we're going to use table.insertexcluded
- 38:12parts and then new bullet just so that
- 38:14the bullets are not going to be
- 38:15interacting with each other. And then
- 38:17we're going to say game. debris colon
- 38:19add item new bullet. And then we're
- 38:21going to get rid of it after 0.5
- 38:23seconds. Just like this. Okay. So what's
- 38:26left to do here is we need to make a
- 38:28couple calculations so that we can be
- 38:30able to change the size and the C frame
- 38:33of this bullet accurately. Okay. So we
- 38:35need to calculate a few things before we
- 38:37continue. So the first thing is the
- 38:39position of the end result or the
- 38:42position of the goal if that makes
- 38:43sense. So basically what I'm trying to
- 38:45say is that we either hit something with
- 38:47the ray that we shot and we're just
- 38:48going to get the position of that or if
- 38:50we don't hit anything then we're just
- 38:52simply going to get the origin plus
- 38:53direction. That's going to give us the
- 38:55information about the position. Another
- 38:58thing we need to calculate is with that
- 39:00position and with the origin point, we
- 39:02want to be able to get the distance
- 39:04between them as well because that's
- 39:06going to be useful for us to know the
- 39:08size of the bullet. And we also want to
- 39:10get the midpoint so that we know where
- 39:12to position the bullet when we shoot it
- 39:15out into the world. So, if we go inside
- 39:17of our script, uh we're going to
- 39:18calculate these three things on top of
- 39:20here. So we're first going to say local
- 39:22position equals and this can either be
- 39:25one of two values. So we're going to say
- 39:27if ray result then so if uh if we
- 39:32actually did get a result from shooting
- 39:34the ray then we're just simply going to
- 39:35say ray results.position.
- 39:39Otherwise we're just going to calculate
- 39:41the origin plus the direction just like
- 39:43this. Next thing we're going to do is
- 39:45calculate the distance. So we're going
- 39:46to say local distance equals open and
- 39:49close parenthesis. We're going to take
- 39:50the position we just calculated. We're
- 39:53going to subtract that from the origin,
- 39:55so where the the gun was shot from. And
- 39:57then we're going to say dot magnitude
- 39:59because we just want the distance. Like
- 40:01we want a fixed number that's going to
- 40:03be telling us the distance. And then the
- 40:05midpoint, which is literally the exact
- 40:07same calculation as we did in visualize
- 40:09ray. So I'm just going to copy and paste
- 40:11that into here. Okay. So now that we
- 40:13have this, let's change the size and
- 40:16frame of this. So with this bullet, this
- 40:19bullet is a cylinder. So we need to
- 40:21figure out a way to make this cylinder
- 40:24work with its size and also its C frame.
- 40:26And I'm going to show you what that
- 40:27looks like here. So we're going to say
- 40:29new bullet do size equals vector 3. And
- 40:33inside of here, we want the X to be the
- 40:36distance. So if we were to fire from the
- 40:39origin over to that wall over there,
- 40:41then the X is just going to be the
- 40:43distance. So for the Y and Z, these two
- 40:46are going to be the same numbers because
- 40:48it's going to be a perfect symmetrical
- 40:50sphere that looks like this. And if you
- 40:52have taken geometry, basically a radius
- 40:55is like half of a circle if you were to
- 40:58determine the distance from the midpoint
- 41:00to one of the outer edges of the circle.
- 41:04So if we want a full circle, we want the
- 41:07diameter, which in this case that's what
- 41:09it's called, which is basically the
- 41:11bullet radius* 2. And for the Z, it's
- 41:15going to be the exact same thing here as
- 41:17well. So this is how we calculate the
- 41:21size for the new bullet. And now what
- 41:23we're going to do is change the C frame
- 41:26of it. So we're going to say new
- 41:27bullet.cframe equals CF frame.look at or
- 41:31you can use Cframe new. It's up to you.
- 41:33We're going to start this at the
- 41:35midpoint. So, this is the location of
- 41:37where this new bolt's going to be. And
- 41:40then we want it to look at the position.
- 41:43So, we want to make it look at the
- 41:45result of the array. Or if it didn't
- 41:47find a result, then it's just going to
- 41:49get the origin plus direction, and
- 41:50that's where it's going to be facing.
- 41:53Okay. But here's the problem, though.
- 41:55So, right now, if we go inside the game,
- 41:58hit test, and hit play. And if we were
- 42:00to try and fire this right now. So what
- 42:03this is going to do is as you can see
- 42:06the bullet is not oriented correctly.
- 42:08But you can see that the size of our
- 42:09bullet is a lot bigger now because we're
- 42:12using sphere casting instead of ray
- 42:15casting. But we just simply want to
- 42:17orient this in a way so that we can
- 42:18actually make the bullet fire from the
- 42:21point to the direction that it's trying
- 42:23to hit. And what we can do is just
- 42:25simply change the orientation of it. So
- 42:27if we go inside of our script, we're
- 42:29just going to multiply this by Cframe.
- 42:34And this takes in three parameters which
- 42:36are all in radians. So we want to change
- 42:39the yaxis specifically. So the x is
- 42:42going to be zero. And then the y is
- 42:44going to be the thing that we're going
- 42:45to change. And then z is just going to
- 42:47be zero as well. So for the y, because
- 42:49this takes in radians and not degrees,
- 42:51we're going to say math.rad open close
- 42:54parenthesis. And we just want to flip
- 42:55this 90°. And that is all that we need
- 42:58to do for this part. So now we're
- 43:00basically done. If we hit play, then
- 43:02what we should see is if we take our gun
- 43:04and we shoot it in a specific direction,
- 43:06then you can see that the bullet is now
- 43:08a lot bigger and we have more range with
- 43:11the bullet. We have a much bigger hitbox
- 43:14because we're using sphere casts rather
- 43:16than ray casting. And I think this is a
- 43:18really useful way of using sphere casts.
- 43:21But of course, there's many practical
- 43:23use cases that you can use with sphere
- 43:25casting and ray casting as a whole. And
- 43:28I hope that the takeaway from this video
- 43:29is you learned a lot about how ray
- 43:32casting works and how to incorporate ray
- 43:35casting inside of your scripts. And this
- 43:37is definitely one of the most fun
- 43:38episodes that I've been able to work on
- 43:40on the channel. And I apologize that it
- 43:42took me a really long time to actually
- 43:44get to this episode. I really wanted to
- 43:46save this episode for one of the last
- 43:47ones just because I think it's really
- 43:49cool just to learn this stuff. It's as I
- 43:52said in the beginning of this episode,
- 43:53raycasting has a wide range of practical
- 43:56use cases that I will not be able to
- 43:58cover inside of one single tutorial
- 44:00episode. So, my hope for this video is
- 44:03that since you've watched all the way
- 44:05through till the end of this really long
- 44:06video, I know that you're definitely
- 44:08dedicated to learning about raycasting
- 44:10and being able to use what you learned
- 44:12from this video and incorporate them
- 44:14inside your scripts or your systems that
- 44:17you're going to be creating for the
- 44:18future. And I can say with confidence
- 44:20that you can definitely use what you
- 44:23learned from this video and incorporate
- 44:25inside your scripts. It just takes a
- 44:26little bit of practice and a little bit
- 44:28of trial and error, but I think you
- 44:29definitely got this. There were a couple
- 44:31things that I left out from this
- 44:33tutorial, otherwise it would have just
- 44:34been too long. Like debunking my turret
- 44:37system that I showed you in the
- 44:38beginning of this episode that is more
- 44:40on the advanced side. And I decided that
- 44:43I'm going to make that a individual
- 44:45video that's going to be over on my
- 44:46Patreon page. So, if you want to support
- 44:48the work that I do and you love the
- 44:50content that I put out, then I will
- 44:51leave a link to my Patreon page in the
- 44:53description if you want to get access to
- 44:54my scripts and also some occasional
- 44:56bonus content that I might put out over
- 44:58there as well. I would also like to give
- 45:00a shout out to my Patreon members for
- 45:01their continued support. Their support
- 45:03has really been helping me continue
- 45:04making the videos that I've been putting
- 45:06out, and I can't appreciate them more
- 45:08than enough. Please share this video
- 45:10with anyone that you think might be
- 45:12interested in learning about raycasting
- 45:14just to get the word around and to help
- 45:15boost this video into the algorithm by
- 45:18also doing things like leaving a like on
- 45:20this video and leaving a comment as
- 45:21well. You can literally comment about
- 45:23anything. Just anything that can help
- 45:25boost this video into the YouTube
- 45:26algorithm. That would be really
- 45:27appreciative. Like I do spend a lot of
- 45:29hours researching each and every one of
- 45:31these videos to try to make them as high
- 45:33quality as they can be for you guys to
- 45:36to really learn these scripting
- 45:37concepts. and I'm really appreciative of
- 45:39you for sticking around this long in the
- 45:42advanced scripting tutorial guide and
- 45:43what we've been able to accomplish
- 45:45throughout this entire journey and I'm
- 45:48really thankful for that. So that is
- 45:50going to be it for this episode on
- 45:52raycasting. I hope you enjoyed this
- 45:54episode and you learned a lot from it
- 45:56and I will see you in the next one.
- 46:00Take
About this transcript
This page contains the full transcript of Raycasting (Guns, Visualizers, Shapecasts) - Roblox Advanced Scripting #37 (2025) by BrawlDev, generated from the public captions YouTube serves with the video. The transcript has 9,048 words across 1,227 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.