19 KiB
Low-Poly FPS Zombie Survival: Complete Implementation & Level Building Walkthrough
This comprehensive guide expands upon the LowPolyFPSGuide specification, providing a complete end-to-end blueprint for building a commercial-quality, low-poly FPS zombie survival game in Unity using the Universal Render Pipeline (URP), Synty Studios assets, and Unity's modern package ecosystem.
Table of Contents
- Architecture & System Flowchart
- Project Configuration & Physics Matrix
- Asset Ingestion & Rigging (Synty Studios)
- Player Character Implementation
- Weapon & Ballistics Systems (Hitscan & Projectiles)
- Pickups & Resource Economy (Ammo, Health, Weapons)
- Zombie AI & Dynamic Wave Spawners
- Level Design, Navigation, & Environmental Mechanics
- UI Canvas, HUD, & Post-Processing
- Step-by-Step Level Construction Tutorial
- Verification Checklist & Debugging Guide
1. Architecture & System Flowchart
The game is built upon a decoupled, event-driven architecture where player actions, weapons, pickups, and enemies communicate cleanly via dedicated managers.
+----------------------+
| UIController (HUD) |
+----------^-----------+
|
+---------------+---------------+
| | (Health changed, Ammo updated,
| | Zombies left, Banners)
+---------+--------+ +--------+--------+
| Player Controller| | AreaClearance |
| & Health System | | Manager |
+----+--------+----+ +----+-------+----+
| | | |
(Move/Look)| | (Damaged/Healed) | | (All cleared)
v v v v
+-------+---+ +--+-----------+ +------+---+ +-+-----------+
|Character | |Health & Ammo | | Enemy | |Interactive |
|Controller | |Pickups | | Spawner | |Doors & Exit |
+-----------+ +--------------+ +----+-----+ +-------------+
|
| (Spawns & tracks)
v
+------------------+ +----+-------------+
| WeaponController |<--------->| EnemyController |
| (Hitscan/Rocket) | (Damage) | (Melee & Ranged) |
+------------------+ +------------------+
Script Inventory
All scripts reside under Assets/Scripts/:
PlayerController.cs: First-person locomotion, pitch/yaw clamping, sprinting, jump physics.PlayerHealthController.cs: Singleton managing hit points, damage mitigation, health events, and game over.Weapon.cs: Multi-mode weapon supporting both raycast hitscan and physical explosive projectiles, ammo reserves, and reload logic.WeaponsController.cs: Weapon switching, inventory slots, fire triggers, and HUD communication.Projectile.cs: Physical ballistic / explosive projectile with collision sweeping, splash damage falloff, and impact effects.PickupItem.cs: Base class for world pickups featuring procedural hover bobbing, 3D rotation, and respawn logic.AmmoPickup.cs: Replenishes current weapon magazine or reserve ammo.HealthPickup.cs: Restores player HP viaPlayerHealthController.WeaponPickup.cs: Unlocks and auto-equips new weapons found in the arena.EnemyController.cs: NavMesh-driven state machine (Idle, Chase, Attack, Dead) supporting melee strikes or ranged projectile spitting.EnemySpawner.cs: Configurable spawn waves with editor gizmos, managing living enemy quotas.AreaClearanceManager.cs: Objective tracker unlocking arena gates and scene exits when all hostiles are eliminated.HazardZone.cs: Environmental hazard dealing damage over time or instant death (slime, fire pits, kill planes).InteractiveDoor.cs: Animated gate opening upon objective clearance or proximity.LevelExit.cs: Transition volume loading subsequent scenes.UIController.cs: Singleton updating HUD sliders, ammo readout, kill counters, dynamic banners, and game-over screens.
2. Project Configuration & Physics Matrix
2.1 Package Requirements
Ensure the following packages are present in Packages/manifest.json:
- Universal RP (
com.unity.render-pipelines.universal) - AI Navigation (
com.unity.ai.navigation) - Input System (
com.unity.inputsystem) - TextMeshPro / UGUI (
com.unity.ugui)
2.2 Layer Configuration
Open Edit > Project Settings > Tags and Layers and set up User Layers:
- Layer 3:
Player - Layer 6:
Enemy - Layer 7:
Ground - Layer 8:
Interactable - Layer 9:
Projectile - Layer 10:
Hazard
2.3 Physics Collision Matrix
Navigate to Edit > Project Settings > Physics:
- Enemy vs Enemy: Uncheck to allow zombies to swarm without getting snagged on each other's colliders.
- Projectile vs Player: Uncheck so player projectiles never hit the shooter.
- Projectile vs Enemy: Check to register direct weapon hits.
- Projectile vs Ground: Check so missed shots hit walls, floors, and obstacles.
3. Asset Ingestion & Rigging (Synty Studios)
3.1 Model Import & Rigs
- Select all character FBX models (e.g. Synty POLYGON Apocalypse, Zombies, or City).
- In the Rig tab:
- Animation Type: Set to
Humanoid. - Avatar Definition: Set to
Create From This Model. - Click Apply.
- Animation Type: Set to
- In the Materials tab:
- Set material shader to
Universal Render Pipeline/LitorUniversal Render Pipeline/Simple Lit. - Assign the bundled Synty texture palette atlas (e.g.,
PolygonApocalypse_Texture_01_A.png).
- Set material shader to
3.2 Socket Hierarchy
To cleanly position weapons in the player's or character's hands:
- Expand the character rig:
Root > Pelvis > Spine > Upper_Chest > R_Clavicle > R_UpperArm > R_Forearm > R_Hand - Create an empty child GameObject named
Weapon_Socket_R. - Set its local position and rotation to align with your weapon grip.
4. Player Character Implementation
4.1 Player GameObject Hierarchy
Build the player GameObject as follows:
Player (Tags: "Player", Layer: "Player")
|-- CharacterController (Height: 1.8, Radius: 0.35, Center: 0, 0.9, 0)
|-- PlayerInput (Default map: "Player")
|-- PlayerController.cs
|-- PlayerHealthController.cs
|-- WeaponsController.cs
|-- CameraHolder (Local Position: 0, 1.6, 0)
|-- Main Camera (Local Position: 0, 0, 0)
|-- Weapon_Socket (Local Position: 0.25, -0.25, 0.5)
|-- Gun_01_Rifle (Active)
|-- Gun_02_RocketLauncher (Inactive)
4.2 Configuring Inspector Fields
- PlayerController:
Walk Speed:5.0Sprint Speed:8.5Gravity:-19.62Jump Height:1.2Camera Holder: DragCameraHoldertransform.Mouse Sensitivity:2.0Up Down Look Limit:80.0
- PlayerHealthController:
Max Health:100
- WeaponsController:
Weapon Slots: Size2(Assign equippedGun_01_RifleandGun_02_RocketLauncher).Player Camera: DragMain Camera.Hit Mask: SelectDefault,Ground,Enemy.
5. Weapon & Ballistics Systems (Hitscan & Projectiles)
The included Weapon.cs supports two distinct ballistics paradigms out of the box:
5.1 Hitscan Weapon Setup (Assault Rifle / Pistol / Shotgun)
For immediate bullet registration (instant raycast):
- Attach
Weapon.csto the rifle model. - In the Inspector:
Weapon Name:Assault RifleDamage:25Fire Rate:0.12Range:100Max Ammo:30Reload Time:1.5Use Projectile: Unchecked (false)Infinite Reserve:falseCurrent Reserve Ammo:90Max Reserve Ammo:180Muzzle Flash: Assign muzzle ParticleSystem.Impact Effect Prefab: Assign spark / dust impact prefab.Muzzle Point: Child empty GameObject placed at barrel tip.
5.2 Physical Projectile Setup (Rocket Launcher / Grenade / Plasma)
For weapons that launch physical geometry with travel time and splash damage:
- Create a
Rocket.prefab:- Add a 3D projectile model.
- Add a
SphereCollider(Is Trigger =true). - Attach
Projectile.cs. - Configure
Projectile.cs:Speed:40Life Time:5Damage:80Is Explosive:trueExplosion Radius:4.5Impact Effect Prefab: Assign explosion VFX prefab with light flash.
- Attach
Weapon.csto the launcher GameObject:Use Projectile: Checked (true)Projectile Prefab: DragRocket.prefab.Projectile Speed:40Fire Rate:0.8Max Ammo:4
6. Pickups & Resource Economy (Ammo, Health, Weapons)
All pickups inherit from PickupItem.cs, providing smooth continuous rotation and hover sine-wave bobbing.
6.1 Health Pickup
- Create a 3D Medkit prefab.
- Add a
BoxCollider(Is Trigger =true). - Attach
HealthPickup.cs:Heal Amount:35Only Collect When Damaged:truePickup Message:"+35 Health Restored"Respawns:true(Respawn Time:20s)
6.2 Ammo Pickup
- Create an Ammo Crate prefab.
- Add a
BoxCollider(Is Trigger =true). - Attach
AmmoPickup.cs:Ammo Amount:30Target Weapon Name: Leave blank to feed active weapon, or enterAssault Rifle.Pickup Message:"+30 Ammo Acquired"Respawns:true(Respawn Time:15s)
6.3 Weapon Pickup
- Place a weapon on a pedestal in the arena.
- Add a
SphereCollider(Is Trigger =true). - Attach
WeaponPickup.cs:Weapon Slot Index:1(Unlocks/swaps to secondary weapon).Pickup Message:"Rocket Launcher Acquired!"Respawns:false
7. Zombie AI & Dynamic Wave Spawners
7.1 Zombie Prefab Assembly
- Drag a Synty Zombie FBX model into the scene.
- Add components:
CapsuleCollider: Center(0, 0.9, 0), Radius0.3, Height1.8.NavMeshAgent: Speed3.5, Angular Speed180, Stopping Distance1.5, Height1.8, Radius0.3.Animator: Assign your Zombie Animator Controller.EnemyController.cs:Max Health:60Attack Damage:15Attack Range:1.8Attack Cooldown:1.2Detection Radius:18- Tag:
Enemy, Layer:Enemy.
- Save as
Assets/Prefabs/Enemies/Zombie_Standard.prefab.
7.2 Ranged Zombie Variant (Acid Spitter)
- Duplicate
Zombie_Standard.prefabto createZombie_Spitter.prefab. - In
EnemyController.cs:Is Ranged Enemy:trueAttack Range:12Ranged Projectile Prefab: Assign an acid blob projectile withProjectile.cs(configured withDamage = 10,Speed = 20).Projectile Spawn Point: Transform at the zombie's head or mouth.
7.3 Dynamic Wave Spawning (EnemySpawner.cs)
Instead of manually placing all zombies, place EnemySpawner objects around the map:
- Create an empty GameObject
WaveSpawner_Courtyard. - Attach
EnemySpawner.cs. - Create several child transforms around the perimeter as spawn points and drag them into the
Spawn Pointsarray. - Set:
Total Enemies To Spawn:15Time Between Spawns:2.5Max Simultaneous Enemies:6Spawn On Start:true
- The spawner automatically registers living zombies with
AreaClearanceManager.
8. Level Design, Navigation, & Environmental Mechanics
8.1 Arena Geometry & NavMesh Baking
- Modular Grid Layout: Assemble walls, floors, pillars, and barricades using Synty modular assets. Ensure all floor seams are snapped (
Vkey vertex snapping or grid snapping). - Static Flagging: Select all static environmental props and tick the Static checkbox in the top-right of the Inspector.
- Bake NavMesh Surface:
- Add a
NavMeshSurfacecomponent (fromUnity.AI.Navigation) to the rootEnvironmentGameObject. - Agent Type:
Humanoid. - Click Bake. Verify the walkable areas are highlighted blue in the Scene view.
- Add a
8.2 Environmental Hazards (HazardZone.cs)
To create acid pools, toxic spills, or pitfall kill volumes:
- Place a 3D Plane or Cube over the hazard area.
- Add a
BoxCollider(Is Trigger =true). - Attach
HazardZone.cs:Instant Kill:false(ortruefor bottomless death pits).Damage Per Second:25Damage Enemies:true(Zombies stepping into acid also take damage).
8.3 Clearance-Linked Gates (InteractiveDoor.cs)
- Create a security blast door or gate blocking progression.
- Attach
InteractiveDoor.cs:Open Offset Position:(0, 3.5, 0)(Slides upwards).Open On Area Cleared:true.
- When
AreaClearanceManagerclears the final enemy, the door smoothly slides open.
8.4 Objective & Exit Portal (AreaClearanceManager.cs & LevelExit.cs)
- Create an empty GameObject
GameManager. - Attach
AreaClearanceManager.cs. - Create an exit portal GameObject (e.g. glowing doorway or teleporter).
- Add a
BoxCollider(Is Trigger =true). - Attach
LevelExit.cs(SetNext Scene Nameto"Level 2"). - Drag the exit portal GameObject to the
Level Exitfield onAreaClearanceManager. The exit stays disabled until all enemies are defeated.
9. UI Canvas, HUD, & Post-Processing
9.1 HUD Hierarchy
Create a Canvas (Render Mode: Screen Space - Overlay, Canvas Scaler: Scale With Screen Size, 1920x1080):
HUD_Canvas
|-- UIController.cs
|-- HealthBar (Slider, anchored Bottom-Left)
| |-- Background (Dark Red)
| |-- Fill (Bright Green)
|-- AmmoText (TextMeshProUGUI, anchored Bottom-Right: "30 / 90")
|-- ZombieCountText (TextMeshProUGUI, anchored Top-Center: "Zombies Left: 12")
|-- NotificationText (TextMeshProUGUI, anchored Center: "")
|-- GameOverPanel (Panel, fullscreen dark overlay, inactive by default)
|-- TitleText ("YOU DIED")
|-- RestartButton (Calls UIController.RestartCurrentScene)
9.2 URP Post-Processing Volume
- Create a
Global VolumeGameObject. - Add a
Volumecomponent, set toGlobal, and assignDefaultVolumeProfile. - Add overrides:
- Vignette: Intensity
0.35, Smoothness0.4. - Color Adjustments: Post Exposure
0.2, Contrast20, Saturation-15(bleak apocalyptic grading). - Bloom: Threshold
1.0, Intensity1.2. - Film Grain: Type
Thin 1, Intensity0.3.
- Vignette: Intensity
10. Step-by-Step Level Construction Tutorial
Here is the exact step-by-step sequence to construct a functional combat arena from scratch:
- New Scene: Create a new scene (
File > New Scene > Basic URP). Save asAssets/Scenes/Level1.unity. - Build Floor & Boundaries:
- Create an empty root GameObject
Environment. - Snap modular floor tiles to cover a 40x40 meter arena.
- Add perimeter walls (height at least 4 meters) to prevent the player or enemies from falling out.
- Add interior cover: barricades, containers, low walls, crates.
- Select
Environmentand check Static.
- Create an empty root GameObject
- Bake NavMesh:
- Add
NavMeshSurfacetoEnvironment. - Click Bake. Ensure navigation mesh flows smoothly around all obstacles.
- Add
- Deploy Player:
- Create the
PlayerGameObject at(0, 1, 0). - Attach
CharacterController,PlayerInput,PlayerController,PlayerHealthController,WeaponsController. - Create
CameraHolderat(0, 1.6, 0)with childMain Camera. - Attach
Gun_01_Rifleto the camera or hand socket withWeapon.cs. - Connect all references in the Inspector.
- Create the
- Place Pickups:
- Drop 2x
HealthPickupand 3xAmmoPickupin strategic side corridors and behind barricades.
- Drop 2x
- Place Hazards:
- Create a green glowing acid pool in the arena center with
HazardZone.cs.
- Create a green glowing acid pool in the arena center with
- Deploy Enemy Spawners:
- Place 2x
EnemySpawnerGameObjects at opposite ends of the arena. - Add 3 spawn transform nodes to each.
- Assign
Zombie_Standard.prefaband set total spawns to 8 each.
- Place 2x
- Set Up Objectives & Exit:
- Place
GameManagerwithAreaClearanceManager.cs. - Place an exit portal zone with
LevelExit.csbehind anInteractiveDoor.
- Place
- Configure HUD & Lighting:
- Add the
HUD_CanvaswithUIController.cs. - Add directional sunlight with soft shadows and a
Global Volumewith color grading.
- Add the
- Test Play:
- Hit Play. Walk, sprint, fire weapons, shoot zombies, collect ammo and health, clear the wave, and proceed through the unlocked exit!
11. Verification Checklist & Debugging Guide
| System | Expected Behavior | Troubleshooting |
|---|---|---|
| Locomotion | WASD moves player; Shift sprints; Space jumps smoothly; mouse looks around without flipping. | Verify CameraHolder is assigned in PlayerController. Ensure CharacterController is enabled. |
| Input System | Firing responds to left mouse button; Reload responds to R; switching responds to Q/E or scroll. | WeaponsController supports both Fire and default Attack input action names. |
| Hitscan Weapons | Bullets hit target immediately; spawn impact VFX at hit point; reduce zombie health. | Check hitMask in WeaponsController includes Enemy layer. Verify Zombie has a Collider. |
| Projectiles | Rockets travel forward; explode on impact; apply splash damage to nearby enemies. | Ensure Projectile.cs has correct Damageable Layers and Is Explosive is ticked. |
| Ammo Reserves | Firing decrements magazine; reloading transfers from reserves; empty ammo triggers click sound. | Check Infinite Reserve setting on Weapon.cs. |
| Pickups | Walking over medkit or ammo crate consumes item, plays SFX, and displays on-screen toast. | Verify pickup collider has Is Trigger checked. Ensure player GameObject is tagged "Player". |
| Zombie AI | Zombies detect player within 18m, chase along NavMesh, swing melee attack within 1.8m. | Verify NavMesh was baked (NavMeshSurface). Ensure Zombie has NavMeshAgent enabled. |
| Wave Spawning | Enemies spawn sequentially up to the max living quota; auto-register with clearance manager. | Verify spawn point transforms are placed above the floor on valid NavMesh ground. |
| Objective Tracker | Defeating each zombie decrements the UI counter; eliminating all opens door and exit portal. | Ensure AreaClearanceManager is present in scene and referenced by LevelExit. |
| Level Transition | Stepping into active exit portal triggers scene load. | Ensure destination scene is registered in File > Build Settings. |