# Unit Formation

## Overview

<mark style="color:blue;">**UnitFormation**</mark> is a component designed to manage the spatial arrangement of units in various formations within a game environment.

## Properties

* **Place On Ground**: Determines whether the formation should align with valid NavMesh surfaces, ensuring units are placed on navigable terrain.
* **Max Ground Distance**: Defines the maximum distance that the component checks to adjust unit positions to the nearest valid ground point from their original formation position.
* **Noise Enabled**: Adds random noise to the formation positions, which can be useful for creating more natural or less grid-like unit positions.
* **Units**: A list of `Transforms` representing the units that are to be arranged in the formation. These units must contain a component which implements <mark style="color:blue;">**IFormationUnit**</mark> to receive new destination commands.

## Public Interface

* **SetUnitFormation(IFormation formation)**

  Sets a new formation pattern for organizing units.
* **ApplyCurrentUnitFormation(UnitFormationData formationData)**

  Applies the specified formation data to the units.
* **CalculatePositions(Vector3 position, Vector3 direction)**

  Calculates the positions for the units based on a specified starting position and directional vector.

## Customisation

Currently the provided components support Unity's **NavMesh** system, but formations do not depend on this. You can use your own navigation system using the <mark style="color:blue;">**IFormationUnit**</mark> interface.

```csharp
public interface IFormationUnit
{
    public void SetTargetDestination(Vector3 newTargetDestination, 
                                     float newFacingAngle);
}
```

## Best Practices

* When using `Place On Ground`, ensure that the scene's NavMesh is properly configured to match the gameplay area as the component relies on this for placing units correctly.
* When `Noise Enabled` is enabled in tight formations, it can lead to disorganised arrangment.
* Regularly update the `Units` list to reflect any runtime changes in the unit group, such as additions or removals. Destroying a unit and not updating it, may result in invalid position calculation because the component it will still count it as living.

#### Example Use Case

```csharp
// Assume this script is attached to a GameObject that manages a group of soldier units
void Start() {
    var formation = new RectangleFormation(10, 5);
    GetComponent<UnitFormation>().SetUnitFormation(formation);
    GetComponent<UnitFormation>().ApplyCurrentUnitFormation(transform.position, transform.forward);
}
```
