Files
LowPolyFPS/LowPolyFPS_Complete_Walkthrough.md

393 lines
19 KiB
Markdown
Raw Permalink Normal View History

2026-10-12 21:28:47 +01:00
# 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](#1-architecture--system-flowchart)
2. [Project Configuration & Physics Matrix](#2-project-configuration--physics-matrix)
3. [Asset Ingestion & Rigging (Synty Studios)](#3-asset-ingestion--rigging-synty-studios)
4. [Player Character Implementation](#4-player-character-implementation)
5. [Weapon & Ballistics Systems (Hitscan & Projectiles)](#5-weapon--ballistics-systems-hitscan--projectiles)
6. [Pickups & Resource Economy (Ammo, Health, Weapons)](#6-pickups--resource-economy-ammo-health-weapons)
7. [Zombie AI & Dynamic Wave Spawners](#7-zombie-ai--dynamic-wave-spawners)
8. [Level Design, Navigation, & Environmental Mechanics](#8-level-design-navigation--environmental-mechanics)
9. [UI Canvas, HUD, & Post-Processing](#9-ui-canvas-hud--post-processing)
10. [Step-by-Step Level Construction Tutorial](#10-step-by-step-level-construction-tutorial)
11. [Verification Checklist & Debugging Guide](#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: `20`s)
### 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: `15`s)
### 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**. |