# Building System Setup Guide

## Overview
The building system allows players to place buildings with:
- **Grid-based snapping** for aligned placement
- **Overlap detection** to prevent buildings from colliding
- **Ground validation** to ensure buildings are placed on terrain
- **Ghost preview** with green (valid) / red (invalid) visual feedback
- **Network synchronization** across all players

## Components

### 1. BuildingData (ScriptableObject)
Defines properties for each building type:
- Building name and prefab reference
- Grid size (width, length, height)
- Placement offset and rotation settings

### 2. Building (MonoBehaviour)
Component attached to placed building instances. Tracks:
- Grid position
- Rotation (0-3, representing 0°, 90°, 180°, 270°)
- Reference to BuildingData

### 3. BuildingManager (NetworkBehaviour - Singleton)
Central manager that:
- Maintains list of all placed buildings
- Validates placement (ground check + overlap detection)
- Handles grid snapping
- Spawns buildings on network via ServerRpc

### 4. BuildingPlacement (NetworkBehaviour)
Player-side building interface:
- Uses new Input System (`PlayerInputActions`, `Keyboard.current`, `Mouse.current`)
- Handles input (B key to toggle, Q/E to rotate, click to place)
- Shows ghost preview at mouse position
- Updates preview material (green/red) based on validity
- Proper input lifecycle management (enable/disable/dispose)

## Setup Instructions

### Step 0: Setup Input Actions (Required First!)
**Before using the building system, you MUST add the required input actions.**

See **INPUT_ACTIONS_SETUP.md** for detailed instructions.

Quick summary - Add these to your Player action map in `InputSystem_Actions.inputactions`:
1. **ToggleBuildMode** (Button) → Keyboard B
2. **Rotate** (Value/Axis) → Keyboard R
3. **Build** (Button) → Mouse Left Button

After adding, save the asset to regenerate the code.

### Step 1: Create BuildingData Assets
1. Right-click in Project window → Create → Northbound → Building Data
2. Configure your building:
   - Assign the building prefab
   - Set grid size (width, length, height)
   - Adjust placement offset if needed
   - Enable/disable rotation

### Step 2: Setup Building Prefabs
For each building prefab:
1. Add `NetworkObject` component
2. Add `Building` component
3. Ensure it has a `Renderer` for preview
4. Add colliders for gameplay (player collision, physics)
5. **Important:** Colliders are NOT used for placement validation - only BuildingData grid size matters
6. Set the prefab's layer to anything EXCEPT the Ground layer (buildings will be raycast-ignored during placement)

### Step 3: Setup BuildingManager
1. Create empty GameObject in your scene named "BuildingManager"
2. Add `BuildingManager` component
3. Add `NetworkObject` component
4. Configure settings:
   - **Grid Size**: Size of one grid unit (default: 1)
   - **Ground Layer**: Layer mask for valid ground (e.g., "Ground")
   - **Available Buildings**: Add your BuildingData assets

### Step 4: Add BuildingPlacement to Player
1. Open your Player prefab
2. Add `BuildingPlacement` component
3. Configure:
   - **Ground Layer**: Same as BuildingManager
   - **Max Placement Distance**: How far player can place (default: 100)
   - **Valid Material**: Green transparent material (auto-created if null)
   - **Invalid Material**: Red transparent material (auto-created if null)

### Step 5: Setup Layers
1. Create a layer named "Ground" (or your preferred name)
2. Assign this layer to terrain/ground objects
3. **Important:** Make sure building prefabs are on a **different** layer (not Ground)
   - This allows raycasting through buildings to hit the ground
   - You can place buildings even when cursor is over existing buildings

## Controls

Default bindings (customizable in Input Actions):
- **B**: Toggle build mode on/off
- **R**: Rotate building (90° increments)
- **Left Mouse Button**: Place building (if valid position)
- **Mouse Movement**: Move preview to placement location

## Input System

The building system uses Unity's **new Input System** with action callbacks:
- Actions: `ToggleBuildMode`, `Rotate`, `Build`
- Subscribe to `.performed` events in `OnNetworkSpawn`
- Unsubscribe in `OnNetworkDespawn`
- No hardcoded keys - all controls defined in Input Actions asset
- Easy to rebind without code changes

**Pattern:**
```csharp
_inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
_inputActions.Player.Rotate.performed += OnRotate;
_inputActions.Player.Build.performed += OnBuild;
```

This uses callback-based input, similar to the pattern shown in `InputSystem_Actions.cs` examples.

## Technical Implementation

### Modern Input System (Callback Pattern)
```csharp
// Initialization in OnNetworkSpawn
_inputActions = new PlayerInputActions();
_inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
_inputActions.Player.Rotate.performed += OnRotate;
_inputActions.Player.Build.performed += OnBuild;
_inputActions.Enable();

// Callback handlers
private void OnToggleBuildMode(InputAction.CallbackContext context)
{
    ToggleBuildMode();
}

private void OnRotate(InputAction.CallbackContext context)
{
    float rotateValue = context.ReadValue<float>();
    // Positive = rotate right, Negative = rotate left
}

private void OnBuild(InputAction.CallbackContext context)
{
    TryPlaceBuilding();
}

// Cleanup in OnNetworkDespawn
_inputActions.Player.ToggleBuildMode.performed -= OnToggleBuildMode;
_inputActions.Player.Rotate.performed -= OnRotate;
_inputActions.Player.Build.performed -= OnBuild;
_inputActions.Disable();
_inputActions.Dispose();
```

### Modern Netcode RPC Pattern
```csharp
[ServerRpc(RequireOwnership = false)]
public void PlaceBuildingServerRpc(int buildingIndex, Vector3 position, int rotation, ServerRpcParams serverRpcParams = default)
{
    // Validation
    if (!IsValidPlacement(...)) return;

    // Server-side spawn
    GameObject obj = Instantiate(...);
    NetworkObject netObj = obj.GetComponent<NetworkObject>();
    netObj.Spawn(); // Automatically syncs to all clients
}
```

## How It Works

### Build Mode Flow
1. Player presses **B** → enters build mode
2. Preview appears at mouse cursor position
3. System raycasts to find ground (two-stage):
   - **Method 1:** Direct raycast to ground, ignoring building colliders
   - **Method 2:** If ground not visible (buildings blocking), raycast to anything, then cast downward from that point to find ground below
   - This allows placement even in completely surrounded cells
4. System checks placement validity:
   - Is there ground below?
   - Does grid bounds overlap with existing buildings?
5. Preview shows **green** if valid, **red** if invalid
6. Player rotates with **R** if desired
7. Player clicks to confirm placement
8. **ServerRpc** sent to server to spawn building
9. Building synchronized to all clients

### Validation System (Grid-Based)
```
IsValidPlacement() checks:
├── Ground Check: Raycast down to find ground
└── Overlap Check: Compare GRID BOUNDS (not colliders!)
    ├── Uses BuildingData width/length/height
    ├── NOT the actual collider size
    └── Rotates grid size automatically (90°/180°/270°)
```

**Important:** Collision detection uses the **grid size** from `BuildingData`, not the physical colliders on the building prefab. This means:
- A building with `width=2, length=3, height=2` occupies a 2x3 grid area
- Even if the visual model is smaller/larger, the grid size determines overlap
- This allows consistent, predictable building placement

### Grid Snapping
- World position → rounded to nearest grid size
- Example: gridSize=2, position (3.7, 0, 5.2) → snaps to (4, 0, 6)

### Rotation System
- Rotation values: 0, 1, 2, 3 → 0°, 90°, 180°, 270°
- Building size auto-swaps width/length when rotated 90° or 270°

## Example Building Setup

### Small House (2x2)
```
Name: Small House
Prefab: SmallHousePrefab
Width: 2
Length: 2
Height: 3
Allow Rotation: true
```

### Wall Segment (1x3)
```
Name: Wall
Prefab: WallPrefab
Width: 1
Length: 3
Height: 2
Allow Rotation: true
```

## Debug Visualization

The system includes visual debugging to help you understand grid placement:

**In Scene View (when build mode is active):**
- **Green/Red Wire Cube**: Shows the grid bounds being checked
  - Green = valid placement
  - Red = invalid (overlapping or no ground)
- **Yellow Grid Cells**: Shows individual grid cells occupied
- **Yellow Sphere**: Grid origin point (snapped position)

**On Placed Buildings:**
- **Cyan Wire Cube**: Shows the grid bounds of placed buildings
- **Yellow Wire Cube** (when selected): Highlights the selected building's grid
- **Magenta Sphere**: Grid position origin

Enable/disable with:
- BuildingPlacement → Show Grid Bounds
- Building → Show Grid Bounds

## Troubleshooting

**Preview doesn't appear:**
- Check if BuildingManager.Instance exists
- Verify availableBuildings list has BuildingData
- Ensure Ground layer is set correctly

**Can't place buildings:**
- Check ground layer mask matches terrain
- Verify building prefabs have NetworkObject
- Ensure BuildingManager has NetworkObject and is spawned

**Buildings overlap despite visual gap:**
- Remember: Collision uses **grid size** from BuildingData, not visual model size
- Check the grid bounds in Scene view (cyan wire cubes)
- Adjust width/length/height in BuildingData to match desired grid footprint

**Can't place buildings when cursor is near existing buildings:**
- FIXED: System now uses RaycastAll and ignores building colliders
- Raycasts pass through buildings to hit the ground
- You can place buildings even when cursor is hovering over old ones
- Just make sure buildings are NOT on the Ground layer

**Can't place in center cell when surrounded by buildings:**
- FIXED: Two-stage raycast system
- If direct ground raycast fails, system raycasts to any object then down to find ground
- Works even when all adjacent cells are built and blocking the ground view
- You can fill in gaps surrounded by buildings

**Network issues:**
- BuildingManager must be spawned on network
- Ensure player has BuildingPlacement component with IsOwner

## Extending the System

### Add Building Categories
Edit `BuildingData.cs` and add:
```csharp
public enum BuildingCategory { Housing, Production, Defense }
public BuildingCategory category;
```

### Add Resource Costs
```csharp
[Header("Cost")]
public int woodCost;
public int stoneCost;
```

Then check resources in `BuildingManager.PlaceBuildingServerRpc()`

### Add Build Range Limit
In `BuildingPlacement.UpdatePreviewPosition()`:
```csharp
float distanceToPlayer = Vector3.Distance(transform.position, snappedPosition);
if (distanceToPlayer > maxBuildRange)
    isValid = false;
```

### Multiple Building Selection
Add UI buttons that change `selectedBuildingIndex` in BuildingPlacement

## Notes

- Buildings are spawned on the **server** via ServerRpc
- Preview is **local-only** (each player sees their own preview)
- Ground layer should include all walkable/buildable surfaces
- Grid size should match your game's scale (larger buildings = larger grid)
