Unreal 4 C++ – Simple Shooter Game


SThis prototype is a third-person shooter built in Unreal Engine 4.25 using C++ and Blueprints, developed as part of the Udemy course Unreal Engine C++ Developer: Learn C++ & Make Video Games. The goal was to implement all the foundational systems of a shooter game from scratch — character movement and input, a weapon actor with hit detection and feedback, enemy AI with behavioral decision-making, and a game mode that tracks win and loss conditions in real time.

The Character System is built on a single AShooterCharacter class shared by both the player and all AI-controlled enemies. This is an intentional design choice: rather than creating separate player and AI character classes, the shared base means both use the same health system, the same gun attachment logic, and the same death processing pipeline. The character spawns its weapon (AGun) at BeginPlay, attaches it to the skeletal mesh at the WeaponSocket bone, hides the default bone-bound weapon to avoid mesh clipping, and sets itself as the gun’s owner — establishing the ownership chain that the gun uses to query the firing controller’s view point.

The Weapon System revolves around a line trace fired from the owning controller’s point of view rather than from the gun barrel. This is the standard approach in shooter games because it ensures that what the player sees in the crosshair is exactly what gets hit — firing from the barrel would cause misses whenever the barrel angle diverges from the camera angle. On a successful trace hit, the gun spawns a muzzle flash particle at the MuzzleFlashSocket, plays muzzle audio, spawns an impact particle at the hit location oriented along the shot direction, plays impact audio, and applies FPointDamageEvent to the hit actor. The gun and its owner are excluded from the collision query to prevent self-hits. All visual and audio assets are EditAnywhere properties, making the full weapon configurable from Blueprint without touching C++.

The Enemy AI is driven by a Behavior Tree and Blackboard, with four custom C++ nodes that cover the AI’s full decision loop:

  • UBTService_PlayerLocation runs on every BT tick and writes the player’s world position to a Blackboard vector key unconditionally. This gives the AI permanent awareness of where the player is, used for long-range navigation toward the player.
  • UBTService_PlayerLocationIfSeen also runs every tick but gates the update behind a LineOfSightTo check. If the AI can see the player, it writes the player pawn as an object key; if not, it clears the key. This drives the classic “sight memory” pattern — when the player breaks line of sight, the BT falls through to a search-the-last-known-location branch rather than immediately losing track.
  • UBTTask_Shoot retrieves the AI controller’s pawn, casts it to AShooterCharacter, and calls Shoot() — the same method the player uses. This reuse is the payoff of the shared character class: the AI fires through exactly the same code path as the player, including the same line trace, damage, and effects.
  • UBTTask_ClearBlackboardValue is a generic, key-agnostic task that clears whichever Blackboard key is configured in the editor. Its value is reusability — it can be dropped into any Behavior Tree in the project without modification.

The Game Mode uses a base/derived split to keep rules decoupled from the notification mechanism. ASimpleShooterGameModeBase defines a single virtual method PawnKilled(APawn*) — it is the contract that all game modes in the project can implement. AKillThemAllGameMode overrides it with the concrete rules: if the killed pawn was controlled by a APlayerController, the player lost and the game ends immediately; otherwise, the mode iterates all AShooterAIController instances in the world and checks if every one of them reports IsDead() — if so, the player won. On game end, every controller in the world receives GameHasEnded with the correct winner flag, which triggers the player controller to remove the HUD, show the win or lose screen widget, and schedule a level restart via a timer.

Learning Source

GitHub Repository

Here you can see the YouTube playlist explaining step-by-step how to implement the game.

Leave a comment

Create a website or blog at WordPress.com

Up ↑