Sitemap
CodeX

Everything connected with Tech & Code. Follow to join our 1M+ monthly readers

How to write an aimbot in Unity

5 min readJul 25, 2022

--

Press enter or click to view image in full size

If you play first-person shooter games, chances are you encountered cheaters and wondered about how a cheat like that is made. In online games cheats go against the essence of competitiveness by removing the skill matchup, but in a single player game, carefully implemented aimbots can get the player out of a sticky situation and enhance the flow of the game.

In this simple tutorial, we’ll explore the basics of the math and the implementation needed to make an aimbot that goes beyond Unity’s transform.LookAt . At the end of the tutorial you’ll have the fundamentals to power up your player with an aimbot on platforms where aiming is more challenging.

Find the sample project on my Github, or if you need a more nuanced aim assist solution for your project with various aim assists similar to high profile games, check out my asset Aim Assist Pro!

We aim to achieve something like the following:

Aimbot in action against a strafing target while using a gamepad

I use a gamepad and only strafe left and right and I don’t adjust my look at all. Still, the aimbot helps keep track of the target for me in a more natural, less robotic fashion.

Setup

To help us focus on writing the code that is relevant to our project, I used Unity’s First Person Character Controller asset as a base. A free asset, it covers movement and player input for us so we only need to tend to writing the aimbot itself. If you want to follow along, add this to your assets and import it to your project.

In our example, we’ll rotate the player and change the Cinemachine camera pitch to make the player turn or look up.

The idea

To define an aimbot, we need to consider the following:

When a target is found, move the crosshair to a certain point over a certain amount of time.

This leads us to find a solution to the problems below:

  1. Find a target to enable the aimbot, but not through walls
  2. Decide which direction — left or right, up or down — to move the crosshair to
  3. Figure out how much adjustment to make over each frame

Luckily, Unity already provides us with SphereCast which we can use to have a radius for our aimbot. If it hits a target, we begin aimbotting.

Get Ágoston Romhányi’s stories in your inbox

Join Medium for free to get updates from this writer.

To decide the direction to turn to, we need to calculate a signed angle between where we are looking (player forward) and where we are supposed to look (the direction to the target). We need to do this calculation for both out turn and pitch adjustments separately.

Press enter or click to view image in full size
Calculating turn angles
Press enter or click to view image in full size
Calculating pitch angles

On the separate axes, once we figure out the difference between the desired look direction and our current look direction we then know which way to turn the player. After this, from the time it should take to look at the target and the player’s distance to the target we can calculate an angular velocity, which rotates the player over the current frame’s time.

The implementation

We want to have something like the following:

Our script needs the player’s first person camera, a radius for the aim assist and the rotation to target time in seconds.
TrackTarget finds and calculates the tracking to a target for a frame-long time. It has to be called by the controller script after every player look input method call. We’ll return the pitch addition in degrees and the euler angles of the turn addition — adding these to the Cinemachine target pitch and the player rotation respectively will issue the necessary look adjustments to aimbot properly.

The first step is shooting the SphereCast to find us a target to aimbot against.

Finding a target with SphereCast

We cast a sphere from the camera to its forward direction. If we didn’t find anything or the collider we found is not an enemy, return null, else return the found target’s transform.

Then, we’ll need to calculate the total angles along each axis.

Calculating the rotation angles on the separate axes

The projections require some explanation here. We project to specific planes (marked by their normal vectors) to distinguish between the horizontal and vertical look axis. Without this projection, Unity’s SignedAngle would calculate a diagonal angle that would result in jittery and inaccurate rotations, unless either horizontally or vertically we are already looking at the target perfectly.

Press enter or click to view image in full size

PF vector shows the player’s look direction and PT vector shows the direction from the player to the target, where we should be looking at. Similarly, PF’ shows the player’s look direction projected to the horizontal plane and PT’ shows the target direction projected to the horizontal plane. β denotes the angle between the unprojected directions and α denotes the angle between the projected directions — in this case it’s the angle on the horizontal axis, which is responsible for the player’s turn.

To calculate the same thing for the pitch, the selected plane to project to is the camera’s right axis.

Calculating angle between a projected look direction and target direction

With the total rotations calculated, we then need to calculate the actual rotations we make during the frame.

We adjust the time to aim so that a narrow aimbot radius doesn’t get stepped over too fast and similarly, a wide one isn’t too slow. We get the distance to the target, then we calculate the angular velocity based on how far we are from the target. Indeed: the closer we are, the faster the aimbot has to turn to meet the time criteria, and the farther we are, the slower it has to turn. We convert this to degrees and divide by time to get the angular velocity. We then pick the least of this “rotation-under-frame” and the total rotation needed or else the aimbot would oscillate back and forth around the center of the target when it’s trying to readjust.
In the end we multiply the result by the direction that came with the total angle calculation by Unity’s SignedAngle .

Integrating the aimbot to Unity’s example controller

The aimbot integration is surprisingly simple:

Similarly to how the example code handles player input, we rotate the player, then set and clamp the camera target pitch and set the camera target’s local rotations to that pitch.

The final result yielded the results you saw as a gif at the beginning of the tutorial.

If you followed through the maths and the code, congratulations! I hope you learned something useful. Make sure to say hi when you drop by my socials and share this article with your fellow developers. Happy coding!

--

CodeX
CodeX

Published in CodeX

Everything connected with Tech & Code. Follow to join our 1M+ monthly readers