Project icon

Raycasting tutorial

Minecraft Version(s)
1.13-1.14.2
Prerequisites:
basic knowledge of
  • tags
  • relative teleportation
  • scoreboard objectives (optional but recommended)
  • /execute command and it's parameters

What is raycasting?
Raycasting is the process of shooting out a beam/ray into the direction the player is looking. This allows us to determine what the player is looking at by detecting collision between our beam/ray and another object or entities.

Why use raycasting?
There are a number of situations where you would need to use raycasting, a good example is casting spells or just shooting in general.

Getting started
In this example, I will be using a carrot on a stick to detect when a player right clicks.

Luckily, Minecraft already has some built-in scoreboard criteria for detecting lots of things including right-clicks with a carrot on a stick so all we need to do is create a scoreboard objective with that criteria. Let's do that:
Code:
/scoreboard objectives add rightClick minecraft.custom:minecraft.used.carrot_on_a_stick
So I've created an objective called "rightClick" which will increment by 1 every time I right click with a carrot on a stick. Now let's use this to shoot out a ray every time we right click.

Obviously, there are no beams/rays in Minecraft so we will use an armor stand as our ray.
Code:
/execute as @a[scores={rightClick=1..}] at @s run summon armor_stand ^ ^ ^1 {Tags:["ray"],Invisible:1,Invulnerable:1,NoGravity:1}
if we right click with our carrot on a stick, the score of our "rightClick" objective increases by 1 and the execute commands can now target us because we met the required criteria. The command will summon an invisible armor stand 1 block in front of us with a tag of "ray" to act as our "ray".

Important note: don't forget to reset the "rightClick" objective back to 0 after the ray has been summoned. Otherwise, the command will summon an infinite amount of rays and your game could crash.
Code:
/scoreboard players reset @a[scores={rightClick=1..}] rightClick
The armor stand is just sitting still at the moment so let's move it in the direction we are looking. But before we do that, we have to rotate the armor stand in the direction we are looking.
Code:
/execute as @e[tag=ray,tag=!facingPlayer] at @s run tp @s ~ ~ ~ facing entity @p
this command will teleport our armor stand to the same position it is currently at but it will also face the armor stand towards the nearest player.

You might have noticed that I added a second tag to the selector called "facingPlayer", this is to prevent the armor stand from constantly rotating towards the player when it teleports forward because we want it to face the direction the player was facing when he right-clicked. To stop the armor stand from constantly facing the player once it has been rotated, we need to add the "facingPlayer" tag to it.
Code:
/tag @e[tag=ray,tag=!facingPlayer] add facingPlayer
the armor stand will now stop rotating and keep its set rotation because it no longer meets the criteria for the rotation command.

The next step is to move the armor stand forward in the direction it is looking. However, the armor stand is looking towards the player which means it would teleport in the opposite direction the player is facing. To get around this, we simply invert the teleportation command to teleport the armor stand backward like so:
Code:
/execute as @e[tag=ray] at @s run tp @s ^ ^ ^-0.5
At this point, we have a working system which shoots out a ray in the direction we are facing every time we right click with a carrot on a stick. Now all that's left to do is detect the collision between our ray and other objects or entities.

The following command will destroy the ray if it collides with a block:
Code:
/execute as @e[tag=ray] at @s unless block ~ ~ ~ air run kill @s
now you could also use this command to perform an action if the ray collides with a block and then destroy it.
example:
Code:
/execute as @e[tag=ray] at @s unless block ~ ~ ~ air run say hi
/execute as @e[tag=ray] at @s unless block ~ ~ ~ air run kill @s
example of entity collision:
Code:
/execute as @e[tag=ray] at @s if entity @e[tag=!ray,distance=..1] run ...
While this works and the rays are destroyed upon collision, you might be wondering what will happen to all the rays that don't collide. They will just fly around your world until you destroy them manually. To prevent this, we could implement a scoreboard timer to destroy all rays after 5 seconds.

let's create the timer objective
Code:
/scoreboard objectives add timer dummy
and now let's increment the "timer" objective for every ray
Code:
/scoreboard players add @e[tag=ray] timer 1
but how do we know how many Minecraft ticks we have to wait for 5 real-life seconds? that's really easy to find out.

20 Minecraft ticks = 1 real-life second, so by that logic 20 * 5 = 100
we have to wait for 100 ticks for 5 seconds in real life
Code:
/kill @e[tag=ray,scores={timer=100..}]
and that's it, that's your raycasting system done. Just paste all of the commands (except the ones where you create the objectives) into a chain of command blocks and set them to always active.

finally, you might want to add some particles to your rays
Code:
/execute as @e[tag=ray] at @s run particle cloud ~ ~ ~ 0.05 0.05 0.05 0.05 20
I hope this tutorial helped you to understand the concept of raycasting at least a little bit.
You can also find all the commands on my Pastebin for easy reading: https://pastebin.com/E615sqSe
Author
MegaCrafter10
Views
913
First release
Last update
Rating
5.00 star(s) 1 ratings

More projects from MegaCrafter10

Top