Weapon HUD, swapping and ammo

Recreating the weapon HUD, ammo system and weapon swap functionality

Introduction

This article expains how the weapon HUD carousel and ammo system works

Final result of the weapon HUD showing current ammo reserves, weapon swapping and ammo pickups

Weapon HUD and ammo system in Destiny 2

In Destiny 2 a player always has 3 weapons equipped. Theres also 3 different types of ammunition types:

To replenish Special and Heavy ammo, Destiny 2 uses a weapon ammo pickup system in which enemies sometimes drop ammo crates when killed, green ammo crates replenish Special ammo and purple ammo crates replenish Heavy ammo.

When it comes to the weapon HUD, the currently equipped weapon is always shown on top, while the unequipped weapons are shown minimized below. The order of the unequipped weapons will always try to respect the originally equipped order, and when swapping weapons it will reorder the unequipped weapons accordingly.

When picking up ammo, a small animation plays as well as showing the amount of newly picked ammo on the side of the UI, and the total reserves number is automatically updated. Finally, when a weapon runs out of ammo, the slot for that weapon turns red and the ammo number starts flashing red.

Example video of the weapon HUD and swapping inside of Destiny 2

Ammo system

The player character has a GAS attribute set that holds info for the current equipped weapon. When a weapon is swapped, the data in the attribute set is saved onto a normal set of variables stored in the Player State (so that ammo counts persist even if a player is killed) and the newly equipped weapons saved attributes are loaded onto the GAS attribute set. This is handled by the WeaponEquipmentComponent in C++. The ammo type each weapon uses can be set up in the weapons WeaponInstance class which is a class that holds all the information about how a weapon functions, and is meant to be extended by blueprints for designers to tweak.

When firing a weapon, the firing cost Gameplay Effect removes 1 ammo from the player’s currently equipped weapon mag ammo attribute. When the magazine runs out of ammo, the GA_Reload ability’s CanActivateAbility function is overloaded to check wether the weapon has enough ammo to be reloaded. For Primary ammo weapons, the reserves are set to -1 to indicate they have infinite ammo:

Overriden CanActivateAbility function

The ammo bricks are actors that inherit from custom C++ classes, DensPickupItem and DensAmmoBrick. When a player collides with the ammo brick collision sphere, the brick will check wether the colliding player’s corresponding ammo type is full or not. If that ammo type is full, the brick will not be picked up.

Special(green) and Heavy(purple) ammo bricks and collisions with a UE5 mannequin for scale

Weapon HUD

The weapon section in the HUD is comprised of a Weapon Carousel Widget which holds three different individual WeaponInfo Widgets

Weapon Info Widget

The weapon info widget gives the player information about the current weapon. It has the following dynamic elements that are initialized when a new weapon is equipped:

  1. Weapon icon
  2. Weapon element icon
  3. Mag ammo
  4. Ammo reserves
  5. Ammo type bar (white, green or purple depending on ammo type)
  6. Recently picked up ammo (+ sign followed by number of ammo goes there)

The following function is called when initializing a new weapon instance with the UI:

Weapon Init function

The weapon info widget also has widget animations that play when the weapon is equipped/unequipped and when ammo is picked up:

The weapon carousel widget holds three separate weapon info widgets. The currently equipped weapon info widget is set at the top, while the unequipped weapons are layed out minimized under it:

Weapon Carousel base layout

When the player swaps weapons, an event is called from C++ in the Weapon Carousel widget that moves the selected weapon to the topmost slot, playing the equipped animation(from the weapon info widget above) while simultaneously playing the weapon unequip animation on the previously equipped weapon. The event then runs a short algorithm that decides where each of the unequipped weapons should be placed in the carousel to try and respect the original equip order.

Once the position of each of the widgets is decided, an FInterp To node is used to smoothly move each of the weapon info widgets to their corresponding location. The following function is ran each tick to simulate a widget animation until the widget position is equal to the target position:

Move to position function. Ran each tick until the condition is met. TargetPosition array calculated by weapon ordering algorithm.

Weapon Ordering Algorithm

The algorithm for ordering the weapons is rather simple and not extremely efficient( O(N^2) ) but since it only iterates an array of 3 items it does its job. (It is designed to be able to support more than 3 weapon slots). The initial slots on the carousel are numbered from 0 to 2 (0, 1, 2).

  1. Initialize array (CarouselNodeEmptyArray) that holds boolean value on wether a slot in the carousel is empty and set the original slot of the weapon to be equipped to empty. (eg if equipping the weapon in slot 1, set the bool array slot 1 to empty)
  2. Set the target position for the newly equipped weapon to the very top slot of the carousel, then create an array EquippedWeaponSlotArray with the remaining weapon slots. (eg if equipping weapon in slot 1, leftover array should be [0, 2] )
  3. Iterate the EquippedWeaponSlotArray array with index j:
    • Iterate the CarouselNodeEmptyArray array starting from the end with index k:
      • If (CarouselNodeEmptyArray[k] is empty) Or If (EquippedWeaponSlotArray[j] >= k):
        1. Set position for target weapon EquippedWeaponSlotArray[j].
        2. Set CarouselNodeEmptyArray[j] to empty and set CarouselNodeEmptyArray[k] to not empty.
        3. Break out of the inner for loop.

Using this algorithm allows the weapons in the carousel to always be ordered. For example if a player has their Heavy ammo weapon equipped and wants to change to their first unequipped weapon, the entire carousel will reorder the Heavy ammo weapon to be at the bottom of the list:

Back to top

Back to project