RayCasting player movment

Hello, I’m new to using RayCast and don’t know too much about it. I’m working on abilities for a game that involve moment like dashing forward and attacking, but lets say an ability goes 50 studs, but there’s only 20 studs in front of me before a wall gets in my way, I don’t want to MELT into the wall or get flung into the stratosphere by basically detecting where a raycast ENDS and then tweening/moving the character’s rootpart to said location.

I know how to tween and do the rest but make a raycast like that is my problem, I’ve looked for youtube videos and the API but it doesn’t quite make sense to me, like having to subtract origin from target, ect.

If anybody can just let me know how to make a raycast that goes forward a set number of studs but gets pushed back by a wall that would mean the world to.

And even if you don’t, thank you for having read for this far and thank you for your time.

2 Likes

Also if I’m dead wrong and raycasting is NOT how I’d do that, please let me know, I’m a somewhat intermediate scripter, still getting used to some of these things and this is my first time with raycasting.

Before you read this, note that I am not EgoMoose, so this is a very crude explanation.

Raycast lets you get the data of whatever is first hit when “casting a ray” from a point in a direction. Think of it like shooting a projectile from a point in a direction and getting the data of what stops the projectile. Raycasts work as long as the direction “reaches” far enough. Let me explain. Here is the basic syntax of a raycast:

workspace:Raycast(origin, dir)

“origin” is where you want to start, and “dir” is the direction you want to go in. If you understand vectors it’s quite easy to figure out. However, if you don’t here’s my best explanation. Vectors have a direction and magnitude. Direction is pretty straight forward. Magnitude on the other hand, is just the length of the vector. I find it easy to visualize this as a triangle. For this scenario, let’s pretend that this vector is a right triangle.

image

As you can see, the triangle has a height of 4 and a width of 3. Hence, we can say that the direction of the vector is (3,4). The magnitude on the other hand, would simply be the hypotenuse of this triangle (assume the triangle isn’t rotated or anything). Now what would happen if we used this vector as a direction in a hypothetical 2d raycast? Well, first off, let’s just assume that the “origin” is (0,0). When we raycast, we set the “starting point” of the vector at the origin. So kind of like this (think of the red like the ray):

If we raycasted at the moment, what would happen?
Absolutely nothing
Why? Because there is nothing for the raycast to “hit”. Well then, what could we hit? Let’s pretend that there is a point that is on the hypotenuse of our triangle:
image
Now, obviously, the raycast could actually hit something and it will return the data of whatever it hits, which in this case would be the point (1,4/3). Note that in Roblox this is very different because I think it returns a table of values. You can check what it actually returns on the docs page.
Ok, now different example. Which point would the raycast return the data of in this scenario:


Well, it would return Mr. Blue point here. Why? Well because it is the first point the ray “hits”. Think of it like a movie theater line. The blue point is the person up next, and purple point is the person behind him. Obviously, you would serve the person next, not the person behind him. Simple enough? How about now, what would happen in this scenario?

Well. Once again, you would get Absolutely Nothing. Typically, without visualizing this vector, it would be hard to find out why your raycast code isn’t working. Most of the time, it is because although the direction is correct, the magnitude is not large enough. As you can see, although the point seems to be in line with the direction, it is not actually on the hypotenuse, so it will not be hit.
One last thing to cover. How on earth does the origin work? Well, let’s say we have an origin of (3,3). What would the raycast look like?

As you can see, the direction and magnitude don’t change. However, where the vector starts does.

Now back to 3d raycasting. It is pretty much the same thing, but with 3 dimensions. Say we want to raycast from the player hrp to a part’s position. What would we do? Well first off, we can write down what we do know:

root -- Assume this is already defined
part -- Assume this is already defined

local ray = workspace:Raycast(root.Position, direction)

What would we put in direction to shoot at root? Well, let’s go back to the 2d triangle again for a second. Say we have a origin of (1,1) and we want to shoot at point (3,4).


What would we do? Well, we would have to subtract the origin from the target point. Why? Well because by subtracting the origin, it generates 2 values that we could reference as a vector (which I will visualize as a triangle):
image
As you can see, the vector would have the width of 2 and height of 3, which happens be the target point minus the origin. Fantastic eh? Now back to where we were. We have the origin at root.Position and the target position at part.Position. We can simply subtract the target point by the origin to get the direction, so our code would look like this:

root -- Assume this is already defined
part -- Assume this is already defined

local ray = workspace:Raycast(root.Position, root.Position-part.Position)

Now that you sort of understand how raycasts works, let’s solve the main issue. We can apply our knowledge of how raycasts work to get the number of possible studs you can go forward. I really don’t want to explain how CFrames work, but essentially, root.CFrame.LookVector gives us a vector that has the forward direction of the root (basically where the root is facing), and a magnitude of 1. Now we obviously have a problem. We can’t use this vector, it only has a magnitude of 1, it wouldn’t hit anything. That is why, we multiply the vector to maintain it’s direction but increase it’s magnitude. Think of it like how similar triangles work:


As you can see, even though the black triangle has double the width and height, it still maintains the same direction, but also has a larger magnitude.
So, now, let’s apply all the knowledge we have been given and create code that will find any block in front of the player within 50 studs. Remember how I said the LookVector had a magnitude of 1? This is very convenient because if we multiply this vector by 50, not only do the dimensions of our theoretical “triangle” increase by a factor of 50, the magnitude also changes by a factor of 50. So here is the code:

root -- Assume this is already defined

local ray = workspace:Raycast(root.Position, root.CFrame.LookVector*50)

Perfect. Now what would “ray” return? Well, from the documentation you can see that if the ray hits nothing, it will return nil. However, if it does hit something, it will return some data points you can then use to find out how far you can dash.

Hopefully this helped you or at least gave you a start on what to do. If you have any questions, feel free to reply or something.

4 Likes

@Pure_Bacn. I must admit. Never once in all my years of development, have I had someone actually sit down and drop roblox lua’s bible equivilant (this is a good thing). I have never been given a more thorough and easy to understand explanation before. For the past like hour or so, I’ve seen you typing and I was sure it was a bug, but I didn’t expect for you to give me the answer I was searching for.

Genuinely, “Thank you” isn’t enough, I appreciate this so much. Thank you SO much for actually going out of your way to help me out.

1 Like

Hey man, I decided to fix up my explanation a bit better and posted this if you want to learn more about raycasting.

1 Like

Thank you, I’ll be looking into it

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.