> For the complete documentation index, see [llms.txt](https://travljen.gitbook.io/object-placement/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://travljen.gitbook.io/object-placement/how-it-works/placement-bounds.md).

# Placement Bounds

Check out how placement bounds function and how to implement your own!

## Overview

For defining object's placement bounds interface <mark style="color:blue;">**IPlacementBounds**</mark> is used, it must define bounds and rotation the object and its reference to `gameObject` itself.

<details>

<summary>Interface</summary>

<pre class="language-csharp"><code class="lang-csharp">/// &#x3C;summary>
/// Interface for providing placement bounds for a placing object.
/// &#x3C;/summary>
<strong>public interface IPlacementBounds
</strong>{
    /// &#x3C;summary>
    /// Root game object of the placing object.
    /// &#x3C;/summary>
    public GameObject gameObject { get; }

    /// &#x3C;summary>
    /// Bounds relative to local position of the root "gameObject".
    /// &#x3C;/summary>
    public Bounds PlacementBounds { get; }

    /// &#x3C;summary>
    /// Absolute rotation of the placing object.
    /// &#x3C;/summary>
    public Quaternion PlacementRotation { get; }
}
</code></pre>

</details>

Provided components which implement this interface:

* <mark style="color:blue;">**APlacementBounds**</mark>: abstract class for implementing custom behaviour
* <mark style="color:blue;">**CustomPlacementBounds**</mark>: defines bounds by `center` & `size` properties
* <mark style="color:blue;">**RendererPlacementBounds**</mark>: supports referencing a specific renderer from which bounds are retrieved
* <mark style="color:blue;">**ColliderPlacementBounds**</mark>: supports referencing a specific collider from which bounds are calculated
* <mark style="color:blue;">**IPlacementBounds**</mark> or <mark style="color:blue;">**APlacementBounds**</mark> can be used to implement your own behaviour for placement bounds

### Auto Bounds Setup

If a placeable prefab does not already have a component that implements `IPlacementBounds`, **Object Placement** attempts to create one automatically on the preview instance.

The fallback order is:

1. `BoxCollider` on the root object -> `ColliderPlacementBounds`
2. `Renderer` on the root object -> `RendererPlacementBounds`

If neither is found, placement cannot begin for that prefab.

During placement, colliders on the preview instance are disabled so the preview object does not block its own placement checks.

### Collider bounds option

`ColliderPlacementBounds` can calculate bounds from a referenced `BoxCollider` or `MeshCollider`.

When `Use Local Bounds` is enabled, bounds are calculated from the collider's local shape. This is useful when rotated bounds should stay aligned with the object instead of using a stretched world-space AABB.

### Utility helpers

`IPlacementBounds` also includes extension helpers:

* `GetHorizontalMax()` returns the largest horizontal bounds axis.
* `GetLowestPointCenter()` returns the bottom-center point of the bounds.

These are useful for custom placement systems such as walls, roads, tiles, or other chained placement flows.

## Best Practices

It is recommended that these bounds are defined in Editor and not at runtime. However it is still possible to do it in code.

**Example 1:**

```csharp
// Assumes this script is attached to the placing object itself
void Awake() 
{
    CustomPlacementBounds bounds = AddComponent<CustomPlacementBounds>();
    bounds.center = Vector3.zero;
    bounds.size = new Vector3(10, 2, 5);
}
```

**Example 2:**

```csharp
// Assumes this script is attached to the placing object itself
[SerializeField] private Renderer mainRenderer;

void Awake() 
{
    RendererPlacementBounds bounds = AddComponent<RendererPlacementBounds>();
    bounds.SetRenderer(mainRenderer);
}
```
