Calculating Distances Tool
Written by J$K
Last updated
Written by J$K
Last updated
For this script we'll be making a more advanced tool than the previous ones. It is recommended that you read the previous examples before this one. Let's make a tool that can calculate & visualize distances in-game.
Let's start off by making a new function that will run every frame, and declare some variables we'll be using.
We created 3 variables that we want to use for later, but don't know what value we want them to hold yet. For this we'll say they are nil values. We also want them to be outside of our function, since we'll want to keep these variables alive. This type of variable is called a global variable.
If we print these values, we can understand that aimingAt is a raytrace from our current position, to wherever our crosshair is pointed (meaning a path from us the player, to whatever our aim has collided with). playerPosition is just our current position that we'll store for later drawing uses.
Next, we can start drawing a line. This will act as a distance line, between us the player, and whatever our trace shall collide with. Let's go line by line for what we need.
aimingAt from our above example, returns a 3D Vector. We created aimingAt2D because we want to turn our 3D coordinates, into something that can be displayed onto 2D (our screen). So, aimingAt2D can be described as the projected world position on our screen, which is a 2D plane. We can then start drawing with this.
Firstly, we draw the line that connects our player, to the outcome of aimingAt2D. Remember that draw.line takes the arguments of(start, end, color, thickness)
We want our line to start at us, the player. Then end at our crosshair's trace.
If we run this in-game, we'll get something that looks like this.
Then, we can add some aesthetics to our line, like a circle at each ending.
Now we can make something that will actually tell us the distance between these two points.
We can then draw this text on screen like so.
Now this isn't that pretty, so we can get creative and come up with a way to make our text always be in the center of our line. To do this we need some vector math.
We want to create a new 3D vector variable that will hold the difference between our two vectors, aimingAt & playerPosition. We can subtract one vector from the other to get this difference.
We then need to only get half of this distance, since that will always be the middle point. We can do it like so.
We add our differenceVector to our aimingAt vector, and scale that by half (.5), we do this so that our new vector scaledVec, can stay inline with our aimingAt vector, whilst only being half it's length. This is quite complicated so we can look at some images that might help explain it.
This picture visualizes our difference between the two vectors. You can think of this as the line we've already drawn in-game. If you want to get the vector between two points, this is the formula to get it: destination - start.
Since we want to center our text, we only need half the difference vector. In order to scale vectors you can multiply it by values bigger than 1 to stretch it, or values between 0 - 1 to shrink it. In our case we used 0.5 meaning 50% of its original length. We can also use negative values to scale our vector in the opposite direction.
With all that explained, we can finally draw our centered text. We'll also offset it a little from the line for easier readability.
With all that said we should be done! Our code should look something like this.
We want our program to calculate distances each time we press/hold our left mouse button. So let's create an if statement that will get a of our current crosshair position.
Just like our draw.line function from above, we need some arguments to pass in. For our first circle, we want it to be placed at the beginning of the line, and our second circle be placed at the end of the line. Note that aimingAt2D is already our projection to screen, whilst playerPosition we need to call upon, since it's still in 3D space. This should give us something a little prettier.
We can take advantage of to calculate this. We then convert this result from a float to a string. It also helps to make our decimal place a bit smaller for readability purposes, in this case only 2 decimal places. If you noticed, we aren't calculating the 2D distances of aimingAt & playerPosition, but the in-game 3D ones.