Files
LowPolyFPS/LowPolyFPS_Complete_Walkthrough.md
2026-10-12 21:28:47 +01:00

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

  1. Architecture & System Flowchart
  2. Project Configuration & Physics Matrix
  3. Asset Ingestion & Rigging (Synty Studios)
  4. Player Character Implementation
  5. Weapon & Ballistics Systems (Hitscan & Projectiles)
  6. Pickups & Resource Economy (Ammo, Health, Weapons)
  7. Zombie AI & Dynamic Wave Spawners
  8. Level Design, Navigation, & Environmental Mechanics
  9. UI Canvas, HUD, & Post-Processing
  10. Step-by-Step Level Construction Tutorial
  11. 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 via PlayerHealthController.
  • 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:

  1. Enemy vs Enemy: Uncheck to allow zombies to swarm without getting snagged on each other's colliders.
  2. Projectile vs Player: Uncheck so player projectiles never hit the shooter.
  3. Projectile vs Enemy: Check to register direct weapon hits.
  4. Projectile vs Ground: Check so missed shots hit walls, floors, and obstacles.

3. Asset Ingestion & Rigging (Synty Studios)

3.1 Model Import & Rigs

  1. Select all character FBX models (e.g. Synty POLYGON Apocalypse, Zombies, or City).
  2. In the Rig tab:
    • Animation Type: Set to Humanoid.
    • Avatar Definition: Set to Create From This Model.
    • Click Apply.
  3. In the Materials tab:
    • Set material shader to Universal Render Pipeline/Lit or Universal Render Pipeline/Simple Lit.
    • Assign the bundled Synty texture palette atlas (e.g., PolygonApocalypse_Texture_01_A.png).

3.2 Socket Hierarchy

To cleanly position weapons in the player's or character's hands:

  1. Expand the character rig: Root > Pelvis > Spine > Upper_Chest > R_Clavicle > R_UpperArm > R_Forearm > R_Hand
  2. Create an empty child GameObject named Weapon_Socket_R.
  3. 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.0
    • Sprint Speed: 8.5
    • Gravity: -19.62
    • Jump Height: 1.2
    • Camera Holder: Drag CameraHolder transform.
    • Mouse Sensitivity: 2.0
    • Up Down Look Limit: 80.0
  • PlayerHealthController:
    • Max Health: 100
  • WeaponsController:
    • Weapon Slots: Size 2 (Assign equipped Gun_01_Rifle and Gun_02_RocketLauncher).
    • Player Camera: Drag Main Camera.
    • Hit Mask: Select Default, 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):

  1. Attach Weapon.cs to the rifle model.
  2. In the Inspector:
    • Weapon Name: Assault Rifle
    • Damage: 25
    • Fire Rate: 0.12
    • Range: 100
    • Max Ammo: 30
    • Reload Time: 1.5
    • Use Projectile: Unchecked (false)
    • Infinite Reserve: false
    • Current Reserve Ammo: 90
    • Max Reserve Ammo: 180
    • Muzzle 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:

  1. Create a Rocket.prefab:
    • Add a 3D projectile model.
    • Add a SphereCollider (Is Trigger = true).
    • Attach Projectile.cs.
    • Configure Projectile.cs:
      • Speed: 40
      • Life Time: 5
      • Damage: 80
      • Is Explosive: true
      • Explosion Radius: 4.5
      • Impact Effect Prefab: Assign explosion VFX prefab with light flash.
  2. Attach Weapon.cs to the launcher GameObject:
    • Use Projectile: Checked (true)
    • Projectile Prefab: Drag Rocket.prefab.
    • Projectile Speed: 40
    • Fire Rate: 0.8
    • Max 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: 35
    • Only Collect When Damaged: true
    • Pickup 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: 30
    • Target Weapon Name: Leave blank to feed active weapon, or enter Assault 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

  1. Drag a Synty Zombie FBX model into the scene.
  2. Add components:
    • CapsuleCollider: Center (0, 0.9, 0), Radius 0.3, Height 1.8.
    • NavMeshAgent: Speed 3.5, Angular Speed 180, Stopping Distance 1.5, Height 1.8, Radius 0.3.
    • Animator: Assign your Zombie Animator Controller.
    • EnemyController.cs:
      • Max Health: 60
      • Attack Damage: 15
      • Attack Range: 1.8
      • Attack Cooldown: 1.2
      • Detection Radius: 18
      • Tag: Enemy, Layer: Enemy.
  3. Save as Assets/Prefabs/Enemies/Zombie_Standard.prefab.

7.2 Ranged Zombie Variant (Acid Spitter)

  1. Duplicate Zombie_Standard.prefab to create Zombie_Spitter.prefab.
  2. In EnemyController.cs:
    • Is Ranged Enemy: true
    • Attack Range: 12
    • Ranged Projectile Prefab: Assign an acid blob projectile with Projectile.cs (configured with Damage = 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:

  1. Create an empty GameObject WaveSpawner_Courtyard.
  2. Attach EnemySpawner.cs.
  3. Create several child transforms around the perimeter as spawn points and drag them into the Spawn Points array.
  4. Set:
    • Total Enemies To Spawn: 15
    • Time Between Spawns: 2.5
    • Max Simultaneous Enemies: 6
    • Spawn On Start: true
  5. The spawner automatically registers living zombies with AreaClearanceManager.

8. Level Design, Navigation, & Environmental Mechanics

8.1 Arena Geometry & NavMesh Baking

  1. Modular Grid Layout: Assemble walls, floors, pillars, and barricades using Synty modular assets. Ensure all floor seams are snapped (V key vertex snapping or grid snapping).
  2. Static Flagging: Select all static environmental props and tick the Static checkbox in the top-right of the Inspector.
  3. Bake NavMesh Surface:
    • Add a NavMeshSurface component (from Unity.AI.Navigation) to the root Environment GameObject.
    • Agent Type: Humanoid.
    • Click Bake. Verify the walkable areas are highlighted blue in the Scene view.

8.2 Environmental Hazards (HazardZone.cs)

To create acid pools, toxic spills, or pitfall kill volumes:

  1. Place a 3D Plane or Cube over the hazard area.
  2. Add a BoxCollider (Is Trigger = true).
  3. Attach HazardZone.cs:
    • Instant Kill: false (or true for bottomless death pits).
    • Damage Per Second: 25
    • Damage Enemies: true (Zombies stepping into acid also take damage).

8.3 Clearance-Linked Gates (InteractiveDoor.cs)

  1. Create a security blast door or gate blocking progression.
  2. Attach InteractiveDoor.cs:
    • Open Offset Position: (0, 3.5, 0) (Slides upwards).
    • Open On Area Cleared: true.
  3. When AreaClearanceManager clears the final enemy, the door smoothly slides open.

8.4 Objective & Exit Portal (AreaClearanceManager.cs & LevelExit.cs)

  1. Create an empty GameObject GameManager.
  2. Attach AreaClearanceManager.cs.
  3. Create an exit portal GameObject (e.g. glowing doorway or teleporter).
  4. Add a BoxCollider (Is Trigger = true).
  5. Attach LevelExit.cs (Set Next Scene Name to "Level 2").
  6. Drag the exit portal GameObject to the Level Exit field on AreaClearanceManager. 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

  1. Create a Global Volume GameObject.
  2. Add a Volume component, set to Global, and assign DefaultVolumeProfile.
  3. Add overrides:
    • Vignette: Intensity 0.35, Smoothness 0.4.
    • Color Adjustments: Post Exposure 0.2, Contrast 20, Saturation -15 (bleak apocalyptic grading).
    • Bloom: Threshold 1.0, Intensity 1.2.
    • Film Grain: Type Thin 1, Intensity 0.3.

10. Step-by-Step Level Construction Tutorial

Here is the exact step-by-step sequence to construct a functional combat arena from scratch:

  1. New Scene: Create a new scene (File > New Scene > Basic URP). Save as Assets/Scenes/Level1.unity.
  2. 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 Environment and check Static.
  3. Bake NavMesh:
    • Add NavMeshSurface to Environment.
    • Click Bake. Ensure navigation mesh flows smoothly around all obstacles.
  4. Deploy Player:
    • Create the Player GameObject at (0, 1, 0).
    • Attach CharacterController, PlayerInput, PlayerController, PlayerHealthController, WeaponsController.
    • Create CameraHolder at (0, 1.6, 0) with child Main Camera.
    • Attach Gun_01_Rifle to the camera or hand socket with Weapon.cs.
    • Connect all references in the Inspector.
  5. Place Pickups:
    • Drop 2x HealthPickup and 3x AmmoPickup in strategic side corridors and behind barricades.
  6. Place Hazards:
    • Create a green glowing acid pool in the arena center with HazardZone.cs.
  7. Deploy Enemy Spawners:
    • Place 2x EnemySpawner GameObjects at opposite ends of the arena.
    • Add 3 spawn transform nodes to each.
    • Assign Zombie_Standard.prefab and set total spawns to 8 each.
  8. Set Up Objectives & Exit:
    • Place GameManager with AreaClearanceManager.cs.
    • Place an exit portal zone with LevelExit.cs behind an InteractiveDoor.
  9. Configure HUD & Lighting:
    • Add the HUD_Canvas with UIController.cs.
    • Add directional sunlight with soft shadows and a Global Volume with color grading.
  10. 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.