Raycasting Basics: Difference between revisions

From Legacy Roblox Wiki
Jump to navigationJump to search
>Pokelover980
New page: This article will teach you how to use the method FindPartOnRay. If you want a practical application for it and not just a document that shows how to use it and ...
m Text replacement - "</SyntaxHighlight>" to "</syntaxhighlight>"
 
(11 intermediate revisions by 4 users not shown)
Line 3: Line 3:
==The Basics==
==The Basics==


As an introduction to raycasting, you'll need to learn how to use the FindPartOnRay method. It takes two arguments, <code>Ray</code> and <code>IgnoreDescendantsInstance</code>. The former is a [[Ray]], while the latter is any [[Instance]]. The second argument is only optional, so I'll cover raycasting with only the first argument at first, and later with the second argument. FindPartOnRay also returns two values, <code>Object</code> and <code>Position</code>. The former is any [[BasePart]] hit by the ray, and the latter is [[Vector3]] of where the ray hit <code>Object</code>. If the ray doesn't hit any object, it will return nil and the point in world space where the ray ended.  
As an introduction to raycasting, you'll need to learn how to use the FindPartOnRay method. It takes two arguments, <code>ray</syntaxhighlight> and <syntaxhighlight lang="lua">ignoreDescendantsInstance</syntaxhighlight> The former is a [[Ray]], while the latter is any [[Instance]] The second argument is optional, so I'll cover raycasting with only the first argument at first, and later with the second argument. FindPartOnRay returns two values, <syntaxhighlight lang="lua">object</syntaxhighlight> and <syntaxhighlight lang="lua">position</syntaxhighlight> The former is any [[BasePart]] hit by the ray, and the latter is the [[Vector3]] position where the ray hit <syntaxhighlight lang="lua">object</syntaxhighlight> If the ray doesn't hit any object, <syntaxhighlight lang="lua">object</syntaxhighlight> will be nil, and Position will be <syntaxhighlight lang="lua">ray.Origin + ray.Direction</syntaxhighlight>


==How to use FindPartOnRay==
==How to use FindPartOnRay==
Line 9: Line 9:
Let's take a look at the following code:
Let's take a look at the following code:


<pre>
local ray = Ray.new(
local Part, EndPoint = Workspace:FindPartOnRay(Ray.new(Vector3.new(5,10,13), Vector3.new(0, 5, 0)))
                Vector3.new(5, 10, 13),
</pre>
                Vector3.new(0, 5, 0)
            )
local part, endPoint = Workspace:FindPartOnRay(ray)


That's the basis of how to use the FindPartOnRay method. The Ray takes two arguments, and the second one is different than the one described on the [[Ray]] page. The first is the start point of the Ray in world space. The second argument is the end point in relation to the start point. So, in this case, it would create a Ray starting at {5, 10, 13} and ending 5 studs above it. You can also think of this as the length vector, as it is how long the ray is. On the Ray page, the second argument is described as being the direction of the Ray, however, with the FindPartOnRay method, this is not the case. You can use it like that if you would like to use a unit vector as a direction, you'd simply have to multiply the vector by 999 (the max distance).
 
That's the basis of how to use the FindPartOnRay method. The [[Ray]] constructor takes two arguments, and the second one is different than the one described on the [[Ray]] page. The first is the start point of the Ray in world space. The second argument is the end point in relation to the start point. So, in this case, it would create a Ray starting at {5, 10, 13} and ending 5 studs above it. You can also think of this as the length vector, as it is how long the ray is. On the Ray page, the second argument is described as being the direction of the Ray, however, with the FindPartOnRay method, this is not the case. You can use it like that if you would like to use a unit vector as a direction, you'd simply have to multiply the vector by 999 (the max distance).


As described before, the method will return nil for the first argument if it doesn't hit anything. If you don't take this into consideration while writing code and you need the BasePart that was hit, you will get errors in your code. We can check if it hit an object simply like this:
As described before, the method will return nil for the first argument if it doesn't hit anything. If you don't take this into consideration while writing code and you need the BasePart that was hit, you will get errors in your code. We can check if it hit an object simply like this:


<pre>
if part then
if Part then
    --Do stuff with the part
  --Do stuff with the part
end
end
</pre>


Since Lua evaluates everything except nil or false as true, we can simply input the part as the condition. That code will prevent errors that would arise from trying to reference the part if it didn't exist.  
Since Lua evaluates everything except nil or false as true, we can simply input the part as the condition. That code will prevent errors that would arise from trying to reference the part if it didn't exist.  
Line 27: Line 28:
Before I briefly mentioned ray length. The max length of the ray is 1000, so you must keep this in mind while casting. If you need a ray longer than this, you can cast one ray, check if it hit anything, and if not, cast another ray starting at the end point of the previous one and continue on. Another note about length is that parts will not be checked outside of the length. Collisions will be tested '''''only''''' between the two points determined by the arguments you supply the ray.
Before I briefly mentioned ray length. The max length of the ray is 1000, so you must keep this in mind while casting. If you need a ray longer than this, you can cast one ray, check if it hit anything, and if not, cast another ray starting at the end point of the previous one and continue on. Another note about length is that parts will not be checked outside of the length. Collisions will be tested '''''only''''' between the two points determined by the arguments you supply the ray.


===IgnoreDescentdantsInstance===
==={{`|ignoreDescendantsInstance}}===


<code>IgnoreDescendantsInstance</code> is the second argument that FindPartOnRay takes. Its use is simple: pass it anything that is an instance and it will ignore it and any descendants of it, as well as those descendants' descendants, and so on. This is very useful if there are parts you want to exclude in your collision check. However, you cannot pass a table in, and it doesn't accept multiple arguments for IgnoreDescendantsInstance, so if there is a group of parts you don't want to check, they should be temporarily grouped into a model, and then you should pass that model to IgnoreDescendantsInstance argument.
<code>ignoreDescendantsInstance</syntaxhighlight> is the second argument that FindPartOnRay takes. Its use is simple: pass it anything that is an instance and it will ignore it and any descendants of it, as well as those descendants' descendants, and so on. This is very useful if there are parts you want to exclude in your collision check. However, you cannot pass a table in, and it doesn't accept multiple arguments for IgnoreDescendantsInstance, so if there is a group of parts you don't want to check, they should be temporarily grouped into a model, and then you should pass that model to IgnoreDescendantsInstance argument.


==Final Notes==
==Final Notes==

Latest revision as of 06:19, 27 April 2023

This article will teach you how to use the method FindPartOnRay. If you want a practical application for it and not just a document that shows how to use it and what each part does, I suggest the article How to Make a Raycasting Lasergun. Now, let's get started.

The Basics

As an introduction to raycasting, you'll need to learn how to use the FindPartOnRay method. It takes two arguments, ray</syntaxhighlight> and

ignoreDescendantsInstance

The former is a Ray, while the latter is any Instance The second argument is optional, so I'll cover raycasting with only the first argument at first, and later with the second argument. FindPartOnRay returns two values,

object

and

position

The former is any BasePart hit by the ray, and the latter is the Vector3 position where the ray hit

object

If the ray doesn't hit any object,

object

will be nil, and Position will be

ray.Origin + ray.Direction

How to use FindPartOnRay

Let's take a look at the following code:

local ray = Ray.new(
                Vector3.new(5, 10, 13),
                Vector3.new(0, 5, 0)
            )
local part, endPoint = Workspace:FindPartOnRay(ray)


That's the basis of how to use the FindPartOnRay method. The Ray constructor takes two arguments, and the second one is different than the one described on the Ray page. The first is the start point of the Ray in world space. The second argument is the end point in relation to the start point. So, in this case, it would create a Ray starting at {5, 10, 13} and ending 5 studs above it. You can also think of this as the length vector, as it is how long the ray is. On the Ray page, the second argument is described as being the direction of the Ray, however, with the FindPartOnRay method, this is not the case. You can use it like that if you would like to use a unit vector as a direction, you'd simply have to multiply the vector by 999 (the max distance).

As described before, the method will return nil for the first argument if it doesn't hit anything. If you don't take this into consideration while writing code and you need the BasePart that was hit, you will get errors in your code. We can check if it hit an object simply like this:

if part then
   --Do stuff with the part
end

Since Lua evaluates everything except nil or false as true, we can simply input the part as the condition. That code will prevent errors that would arise from trying to reference the part if it didn't exist.

Before I briefly mentioned ray length. The max length of the ray is 1000, so you must keep this in mind while casting. If you need a ray longer than this, you can cast one ray, check if it hit anything, and if not, cast another ray starting at the end point of the previous one and continue on. Another note about length is that parts will not be checked outside of the length. Collisions will be tested only between the two points determined by the arguments you supply the ray.

ignoreDescendantsInstance

ignoreDescendantsInstance</syntaxhighlight> is the second argument that FindPartOnRay takes. Its use is simple: pass it anything that is an instance and it will ignore it and any descendants of it, as well as those descendants' descendants, and so on. This is very useful if there are parts you want to exclude in your collision check. However, you cannot pass a table in, and it doesn't accept multiple arguments for IgnoreDescendantsInstance, so if there is a group of parts you don't want to check, they should be temporarily grouped into a model, and then you should pass that model to IgnoreDescendantsInstance argument.

Final Notes

FindPartOnRay is an amazing method, however, it is not always the most useful or efficient thing you could use. If you say, "Oh, hey, this is really easy to use, I'm going to use it whenever possible," I highly suggest you think twice every time you want to use it to see if there's a better way. If you need to check if there is a part in the way of two points, go ahead and use FindPartOnRay. If you need to find all parts within the radius of a certain point, there's probably a better and easier way to do it with Magnitude or another method, but this article isn't about explaining that.

See Also