Working with Unity Raycast

Challenge: Creating an practical use of Raycasting by creating an FPS prototype

Simon Truong
5 min readFeb 14

In this challenge we will be putting our knowledge of Unity Raycasting to an practical usage. We will be creating the ability to instantiate random bullet holes through the center of the screen while also having an spark like particle system spawn from the same spot.

Project Prepping:

For this project to happen, I had the pleasure of having access to Filebase, which is online library created by GameDevHQ. Within this library I was able to download every required VFX, decals and other assets required for this project. But If you are following this project, you are also free to use whatever you desire as your disposal.

From Filebase I decided to download the Bullet hole Decals along with the VFX spark and Target icon.

I also downloaded the First Person Character Controller so I can easily mock up the player movement along with camera movement.

Once I imported all the assets into Unity, I created a new Canvas with an Image directly set in the center of the screen. I replaced the white box image with my choice of Target icon. I also mocked up a 4 by 4 room where I placed the First person character controller in.

The reticles in the center with the camera/FPC inside a 4 by 4 cubed room.
I also got rid of the Main Camera since the FPC already has one by default.

Right away, with the FPC in the scene I am able to move around with the WASD controls. If there is an error, this is due to the fact that the Input System is set to the new version and you must return the settings to use “Both” in the player settings. Unity will prompt to restart the application, and once that is completed you should be able to resume the player controls while playing.

Scripting the Raycast:

First we are going to create a new C# script called “Shooting” and attach this script to the FPC. To start, we are going to first gain access to the New Input system by using the Input System library.

Next I decided to organize the actual shooting function into its own method, therefore I created a shot method, which will be called within the update method.

The Unlock Arrow Cursor is basically the function to hide the mouse arrow during game play.

Inside the Shot method we are going to follow the same basic setup as we did for the other challenges for Left Mouse click and raycasting. The only difference this time is, we want the bullet hole to instantiate from the center fo the screen instead of the current mouse position. Therefore we will need to use a class called “Viewport Point To Ray” and then give it a new vector3 of 0.5x and 0.5y, and zero on the z axis. This setup will directly center all objects instantiated from the center.

Next we are going to instantiate the bullet hole. Since the Filebase asset came with multiple of different bullet hole designs we are going to use all of them.
We also want to limit the types of objects the bullet hole can be targeted so we want to start with an IF statement with a compare tag function checking for objects tagged with “Floor”.

Then we are going to make a new Array called Bullet holes.

Inside the Shot method, we are going to create an local Int variable called Bullet hole number which will equal to a random range of 0 to the actual total bullet array length.

When we start doing the Instantiating, we are going to plug in the new int variable as the number required for the bullet hole array. Then we do the hitInfo dot point for the raycast location input, but since we are worried that the instantiated decal might be too close to the walls and floors, we are going to adjust it by adding a bit of height to the instantiated locations. This is where the “hitInfo.normal * 0.02f” becomes important.

The hitInfo.normal is basically the calculation of the normal surface the ray hits. The float value after that is the additional height increase which we don’t want too much, just enough that the asset is spawned just above the walls and floors. We finally finish off the Instantiated function by adding a rotation. We want the rotation to occur parallels to the player view, therefore we use a class called “Look Rotation” which requires a a vector3. We will again use the hitInfo.normal as the input value.

The next instantiated object is the sparks VFX. Just like what we did with the bullet holes, we will need access to the prefab via Serialized Field.

Then again, within the Shot method in the raycast function, we are going to instantiate the spark prefab using the same Look Rotation. This way once you left click, both the bullet hole and the sparks should happen at the same time in the same place.

Just remember back in Unity we are required to drag and drop all of the bullet hole assets into the script array. Along with the sparks prefab into the serialized slot.
Once you test out the game, the final result should look like the example below. Both the sparks and bullet holes should be instantiated int the same location.

If you find that the sparks particle system is looping continuiously, then you basically need to uncheck the looping option in the particle system.



Simon Truong

A Designer, an Illustrator and a massive tech geek aspiring to become a professional Unity Developer.