Creating Bullet Holes via Raycasting in Unity
Objective: Let’s create some bullet holes at a target reticules location using raycasting in Unity.
Moving on from the previous article which looked at layer masks with raycasting, let’s have a bit of fun and add some bullet holes to a wall where our target reticule raycast clicks.
Getting the Scene Setup
I have just used 2 cubes and stretched them out/rotated to create a wall and a floor.
Then, I downloaded some assets from Filebase — ‘Target_Reticule’ image, ‘Bullet_Hole’ game object and a simple FPS controller which has a capsule as the player, some movement code and a main camera attached to it. Let’s make sure we delete the existing main camera in the scene and change the tag of the FPS Controllers main camera so we don’t have any clashing issues:
Setting Up Target Reticule Image
I want this image to be positioned in the middle of the screen so that as the player moves their aim around the screen it stays in the middle.
Let’s create an Image in the Unity Hierarchy and name it ‘Target_Reticule’
Right click in Hierarchy → UI → Image.
I am then going to make sure that the X and Y positions for the Image are 0 in the Inspector. I can then drag in an image source to use:
The end result should look like this:
As per the other articles I am going to be using the New Input System, so make sure to have this package downloaded and installed in your project with the new backends enabled.
Detecting Mouse Input and Casting a Ray
Getting started, let’s build some simple code to detect mouse input and cast a ray where we able to use some RayCastHit info:
Compared to the previous articles where I used ‘ScreenPointToRay’, this one is going to use ‘ViewportPointToRay’ because I want to return a ray that goes from the main camera through a viewport point. Whereas ScreenPointToRay uses pixels to define it’s measurements, ViewpointPointToRay uses a coordinate system whereby the bottom-left of the screen is (0, 0) on the X and Y axis respectively, and the top-right is (1, 1).
In our case I would like the middle point of both the X and Y axis to find the middle of the screen, so let’s halve the value of both — 0.5f.
This is going to give us our ‘reticulePos’ that we can pass in as a parameter for our Ray.
We are also going to need some information about the collision with the ray and the wall so that we can instantiate a bullet hole game object at the point it collides — RayCastHit ‘hitInfo’.
Getting a Reference to the Bullet Hole GameObject and Instantiating
Let’s Serialize a ‘_bulletHolePrefab’ that we can drag and drop a game object to in the Inspector.
At the same time let’s create a container to hold all our instantiated game objects so that it doesn’t clutter the Hierarchy, which we will set next.
Now, let’s instantiate the bullet holes:
Make sure to get a reference to the newly instantiated game objects so that we can set the parent to the ‘_bulletHoleContainer’.
Checking our progress:
We are instantiating the bullet holes (as seen in the Hierarchy) but they are facing the wrong way:
That means we have a Quaternion issue! Let’s rotate the game objects to face the opposite direction by rotating the Y value 180 degrees.
Checking progress again:
Success! However we have a new issue where the textures are overlapping.
Let’s offset the position of the bullet holes fractionally (closer to the player on the Z axis) so they are not overlapping:
ViewportPointToRay — Unity Documentation
Physics Raycast — Unity Documentation
RayCastHit — Unity Documentation
Ray — Unity Documentation
Casting Raycasts from Mouse Position in Unity
Placing Objects via Raycast Hits in Unity
Raycasting With LayerMasks in Unity
“Click to Move System in Unity”