# Grid-Based Collision System ## How It Works The building system uses **grid-based collision detection**, NOT the actual colliders on building prefabs. ### Grid Bounds vs Collider Bounds ``` ❌ OLD WAY (Collider-based): Building A has BoxCollider (2.5 x 3.7 x 4.2) Building B has MeshCollider (complex shape) → Hard to predict, inconsistent placement ✅ NEW WAY (Grid-based): Building A has width=2, length=3, height=2 in BuildingData Building B has width=1, length=4, height=3 in BuildingData → Predictable, consistent grid placement ``` ## Why Grid-Based? ### Advantages 1. **Predictable**: Buildings snap to grid, easy to understand 2. **Consistent**: Same rules for all buildings, regardless of visual model 3. **Flexible**: Visual model can be any size/shape 4. **Network-Friendly**: Simple data to sync (just grid position + rotation) 5. **Performance**: Fast AABB (Axis-Aligned Bounding Box) checks ### Comparison | Aspect | Collider-Based | Grid-Based | |--------|---------------|------------| | Placement | Visual, complex shapes | Predictable grid cells | | Performance | Slower (physics queries) | Faster (simple bounds check) | | Network Sync | Complex mesh data | Simple int coordinates | | Rotation | Complex recalculation | Swap width/length | | Debugging | Hard to visualize | Easy (grid gizmos) | ## How Grid Size Works ### BuildingData Settings ```csharp [Header("Grid Size")] public int width = 2; // X-axis grid cells public int length = 3; // Z-axis grid cells public float height = 2f; // Y-axis size (can be float) ``` ### Rotation Effect ``` Building: width=2, length=3 Rotation 0° (0): Rotation 90° (1): ┌─────┐ ┌───────┐ │ 2 │ │ 3 │ │ x │ │ x │ │ 3 │ └───────┘ └─────┘ 2 Rotation 180° (2): Rotation 270° (3): ┌─────┐ ┌───────┐ │ 3 │ │ 2 │ │ x │ │ x │ │ 2 │ └───────┘ └─────┘ 3 ``` The `GetSize(rotation)` method automatically swaps width/length for 90° and 270° rotations. ## Visual Examples ### Example 1: Small House ```yaml BuildingData: width: 2 length: 2 height: 3 Grid Footprint (top view): ┌─┬─┐ ├─┼─┤ Occupies 4 grid cells (2x2) └─┴─┘ Visual Model: Can be any size! - Model might be 1.8 x 1.8 (smaller than grid) - Model might be 2.3 x 2.3 (larger than grid) - Collision still uses 2x2 grid ``` ### Example 2: Wall Segment ```yaml BuildingData: width: 1 length: 4 height: 2 Grid Footprint: ┌───────────┐ │ 1 x 4 │ Occupies 4 grid cells (1x4) └───────────┘ When rotated 90°: ┌─┐ ├─┤ ├─┤ Becomes 4x1 ├─┤ └─┘ ``` ### Example 3: Large Building ```yaml BuildingData: width: 4 length: 5 height: 4 Grid Footprint: ┌─┬─┬─┬─┬─┐ ├─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┤ Occupies 20 grid cells (4x5) ├─┼─┼─┼─┼─┤ └─┴─┴─┴─┴─┘ ``` ## Collision Detection Code ### IsValidPlacement (BuildingManager.cs) ```csharp // Get grid size from BuildingData (NOT collider) Vector3 gridSize = data.GetSize(rotation); // Shrink bounds slightly to allow adjacent placement // Without this, Bounds.Intersects() returns true for touching bounds Vector3 shrunkSize = gridSize - Vector3.one * 0.01f; Bounds checkBounds = new Bounds( groundPosition + Vector3.up * gridSize.y * 0.5f, shrunkSize ); // Check against all placed buildings' GRID bounds foreach (var building in placedBuildings) { Bounds buildingGridBounds = building.GetGridBounds(); if (checkBounds.Intersects(buildingGridBounds)) return false; // Overlap detected } ``` **Why shrink by 0.01f?** Unity's `Bounds.Intersects()` returns `true` when bounds are touching (edge-to-edge), not just overlapping. By shrinking the bounds by a tiny amount (0.01 units), we allow buildings to be placed directly adjacent without triggering a false overlap detection. ### GetGridBounds (Building.cs) ```csharp public Bounds GetGridBounds() { // Uses BuildingData size, not collider Vector3 gridSize = buildingData.GetSize(rotation); // Shrink slightly to allow adjacent buildings Vector3 shrunkSize = gridSize - Vector3.one * 0.01f; return new Bounds( transform.position + Vector3.up * gridSize.y * 0.5f, shrunkSize ); } ``` **Note:** The 0.01f shrink is tiny and not visible, but prevents false overlap detection for adjacent buildings. ## Visualizing Grid Bounds ### In Scene View 1. **Enter Build Mode** (Press B) 2. **Look at Scene View** (not Game view) 3. You'll see: - **Green/Red Wire Cube**: Preview's grid bounds - **Yellow Grid Cells**: Individual cells - **Cyan Wire Cubes**: Placed buildings' grid bounds ### Debug Settings **BuildingPlacement:** - `Show Grid Bounds` - Shows preview grid visualization **Building:** - `Show Grid Bounds` - Shows cyan wire cube for this building - `Grid Bounds Color` - Customize visualization color ### Example Scene ``` Scene View: Preview (Green) ┌─────┐ │ 2x3 │ └─────┘ Placed Building (Cyan) ┌───┐ │1x2│ └───┘ Grid Cells (Yellow): ┌─┬─┬─┬─┬─┬─┐ ├─┼─┼─┼─┼─┼─┤ └─┴─┴─┴─┴─┴─┘ ``` ## Best Practices ### 1. Match Grid Size to Gameplay ```csharp // Small decorations width: 1, length: 1, height: 1 // Medium buildings width: 2-3, length: 2-3, height: 2-3 // Large buildings width: 4-6, length: 4-6, height: 3-5 ``` ### 2. Visual Model Can Differ The visual model doesn't need to match grid size exactly: - Overhang/decorations can extend beyond grid - Model can be smaller, leaving empty grid space - Use `placementOffset` to adjust visual alignment ### 3. Height Consideration ```csharp height: 2f // Building is 2 units tall ``` - Used for vertical bounds checking - Prevents buildings on top of each other - Can be float (e.g., 2.5f for tall buildings) ### 4. Colliders Still Needed Building prefabs should still have colliders for: - Player/entity collision during gameplay - Physics interactions - Raycast detection But these are NOT used for placement validation! ## Common Questions **Q: Why is my small model blocking a large area?** A: Check the `width` and `length` in BuildingData. The grid size determines collision, not the visual model. **Q: Buildings overlap visually but can't place?** A: Grid bounds are overlapping. Check Scene view with "Show Grid Bounds" enabled. **Q: How do I make a building take less space?** A: Reduce `width` and `length` in BuildingData. The visual model size doesn't matter. **Q: Can I use fractional grid sizes?** A: `width` and `length` are integers (whole grid cells). Only `height` can be a float. **Q: What if my model is rotated strangely?** A: Grid rotation is separate from model rotation. Grid always aligns to world axes. Adjust model's prefab rotation or use `placementOffset`. **Q: Can buildings be placed directly next to each other with no gap?** A: Yes! The system shrinks bounds by 0.01f to allow adjacent placement. Buildings can touch edge-to-edge. **Q: I want a gap between buildings. How?** A: Increase the `width` and `length` values in BuildingData by 1. For example, change a 2x2 building to 3x3 to add a 1-cell buffer zone. ## Summary ✅ **Use BuildingData grid size** for collision ✅ **Visual model can be any size** ✅ **Predictable, grid-aligned placement** ✅ **Easy debugging with gizmos** ✅ **Fast performance** ❌ **Don't rely on collider size** ❌ **Don't expect pixel-perfect visual collision** ❌ **Don't use colliders for placement validation**