From Concept to Creation: Designing NPC Drones for Drone Dash
This article explores the gameplay mechanics of an indie game called Drone Dash, the demo of which is available for Android devices (mobile) on the Google Play Store. Specifically, we will discuss the NPC drone mechanics, which are responsible for flying drones around a series of checkpoints while subjecting them to the same physical simulation as the player drone.
A Brief overview of the Game
Drone Dash is a drone racing game where the player maneuvers a drone through a series of checkpoints until it completes all three laps. The player competes against two other drones, which are NPCs. I was responsible for developing the gameplay systems for this game when I was still in university, so some of the design decisions may seem naive or rushed.
Here’s a gameplay trailer that shows the NPC agents flying through a path. Sorry for the extreme dark contrast — we were trying to give it a neon vibe, but it didn’t turn out well.
We begin by summarizing the basic requirements of our game, which were no different from any other racing game. Therefore, some of the key gameplay systems developed were:
- Position Manager : Responsible for keeping track of the drone’s position during the race (both player and NPCs).
- Waypoint Manager: encapsulates all the waypoints and checkpoints in our scene and essentially links them up with one another (a linked list of waypoints). Notice the use of the words “waypoint” and “checkpoint.” In our game, every checkpoint is a waypoint, but the vice versa need not be true.
- Drone Physics Controller: The component that is attached to all the drones (either player-driven or NPC drone) and is responsible for providing a physics model for drones (calculating drag forces and constraints on its rotation and thrust forces).
- NPC Controller: essentially the brain of our NPC, which allows the NPC to make decisions during its flight, such as the amount of thrust needed and the axis in which the drone needs to rotate and by what amount. The goal of our NPC Controller is to ensure our drone is always heading in the right direction (which is the direction in which the next waypoint exists), and at every step, this controller is managing thrust and rotation inputs to achieve its goal.
There is plenty of literature on the web for the first three systems. However, the real challenge was designing the NPC Controller, and that’s what we’ll be discussing in this article. We will also briefly cover the waypoint system because the NPC Controller makes use of it.
Digging deep into the NPC Behavior
One of the design decisions I had in mind when working on this game was to ensure that the NPC drones are subjected to the same physics simulation as the player’s drone. This decision posed a good learning exercise and made the drone movements look more natural.
The NPC drone has no special advantage over the player’s drone.
It experiences the same forces and challenges as the human drone. The thrust vector is always pointing up, which is the up axis of the drone and not the world space.
The controller, whether it’s the player or an NPC, must manage the thrust vector magnitude and rotate the drone (roll/pitch/yaw). As a result, the thrust vector also rotates, and the horizontal component of the thrust vector eventually allows the drone to move in a particular direction
In an actual quadcopter, trying to hover and maintain its altitude, there are 4 thrust vectors on each corner of the drone, providing equal thrust & parallel to each other.
The sum of these thrust vectors is equal/greater in magnitude to the downward gravitational force. In our game, however, instead of simulating all four forces per drone, we’re only using a single thrust vector, which represents the sum of the four thrust vectors.
We apply a simple rotation transformation to rotate the drone, and this rotation applied to the model also affects the direction of our thrust vector, inducing a horizontal motion in the direction intended by the user/controller (see Figure-1).
Since the NPC Controller is always trying to maneuver the drone toward a waypoint, every waypoint maintains a reference to the next waypoint. Once a drone goes through a waypoint, it updates the target waypoint to be the next one referenced by the old waypoint we just crossed.
here’s another screenshot that shows a drone & some of the related vectors
ignore the yellow-colored vector which represents the velocity vector.
Notice blue line coming out of drone and ending at the red cube, this line represents the vector from drone to its next target waypoint, basically the direction in which our drone should be flying (ideally!)
At every frame, the NPC Controller performs the following tasks
1. Projecting Vectors onto same horizontal plane (defined by Vector3.up in Unity)
- The velocity vector of the NPC is projected onto horizontal plane.
- The drone’s forward vector is projected onto horizontal plane.
- Waypoint’s forward vector is also projected onto horizontal plane.
We’re projecting these vectors on the horizontal plane since the vertical component of a vector is not relevant to the movement or behavior of the game object, and may introduce unnecessary complexity in calculations.
By projecting the vectors onto a horizontal plane, the calculations can be simplified as only the relevant components of the vectors are considered. Additionally, drones in our game are intended to move or navigate only on a horizontal plane, while we’ve a separate code to handle altitude differences as described below.
2. Altitude Change
- If the altitude of the NPC is not close to the altitude of the next waypoint, the NPC adjusts its altitude by applying a proportional force.
- The altitude threshold is used to determine whether the drone needs to climb or descend to reach the target waypoint. For example, if the altitude threshold = 2 meters, and the drone is currently at an altitude of 10 meters, and the target waypoint is at an altitude of 15 meters, then the altitude delta will be 5 meters.
- Since 5mtr > 2mtr (altitude threshold), the drone will be moved to a point directly above the target waypoint at an altitude of 15 meters. On the other hand, if the altitude threshold is set to 2 meters, and the drone is currently at an altitude of 10 meters, and the target waypoint is at an altitude of 12 meters, then the altitude delta will be 2 meters.
- Since delta (2m) ≤ threshold (2m), the drone will continue to move directly to the target waypoint without any change in altitude/thrust.
- This approach ensures that the drone follows a smooth trajectory as it moves between waypoints, and avoids any sudden changes in altitude that could make the flight path appear unnatural. It also ensures that the drone stays close to the specified flight path, even if the waypoints are located at different altitudes.
- It is also important to mention that altitude Threshold is defined per waypoint, ideally there would be some default value, but it is possible for waypoints to specify their own thresholds.
3. Rotation and Forward Motion
- If the NPC is aligned with the next waypoint within a certain angle threshold, it moves forward towards the waypoint by applying a force.
- It begins by checking if it is heading towards the waypoint, we do this simply by considering drone’s velocity vector, if no velocity, we’ll consider drone’s facing direction (drone’s forward vector).
- now, we shoot a raycast from NPC position, in the direction of drone’s velocity/forward vector. If this raycast hits the target checkpoint (it could be possible that the raycast hits some other checkpoint, but we only need to check for target checkpoint) then we can be sure that indeed we’re moving in the right direction. This entire logic in our case is within a seperate function that returns a boolean.
- Now there are 2 possibilities
- Drone Heading Toward Waypoint: Now even though it is possible that we’re on-course to pass-through the waypoint, but we still try to ensure that we come in parallel to the waypoint’s forward vector. For this, we check the difference between the angle of drone velocity vector and waypoint’s forward vector. Based on this information, we rotate the drone around Y axis and the amount of rotation applied is directly proportional to the angle between the 2 vectors.
- Drone Not Heading Towards Waypoint : If a drone is not facing towards the waypoint, we rotate the drone to face towards the waypoint’s center point. We also tilt the drone in the direction of the turn. (If a drone is not heading toward waypoint, ideally it could also mean that our raycast is blocked by some other object and we’re heading toward an obstacle, but in our game, we’re ignoring obstacle avoidance for sake simplicity. This also introduced some glitches in existing game)
4. Update Target Checkpoint
- If the NPC has passed through the current checkpoint/waypoint, the next waypoint is then set as the new target for the drone.
Overall, these calculations and adjustments work together to enable the NPC to navigate through a series of waypoints and checkpoints in the game world.
I was not involved in asset creation for this game, credit for that goes to the respective team members whose names are mentioned in the game.