# Selectable Group Unit

## Overview

There are 2 components required to use the functionality for group selection without any coding. This would be the <mark style="color:blue;">**SelectableGroupUnit**</mark> (for every  moving unit) and <mark style="color:blue;">**SelectableGroup**</mark> (for group of units). These components extend the [selectable-unit](https://travljen.gitbook.io/unit-selection/how-it-works/selectable-unit "mention") and provide the same functionality with few additions to achieve smooth group selection.

Both selectable group and selectable group unit support selection indicator visuals. Example would be for individual units to show selection circles and group itself to show floating text, health bar or other additional information about the selected or highlighted group unit.

<figure><img src="https://425343605-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fml7vS0D5xN2Q8jQMEmBv%2Fuploads%2FTywcpPGG5dMcfF6cz6LT%2Fselection%2033%20fps%20gif.gif?alt=media&#x26;token=b64bac2e-80b4-4b29-a6a9-b4c73131f22d" alt=""><figcaption><p>Group selection Demo scene</p></figcaption></figure>

## Configuration

<mark style="color:blue;">**SelectableGroupUnit**</mark> has all the properties already present on <mark style="color:blue;">**SelectableUnit**</mark>. Additionally it implements <mark style="color:blue;">**ISelectableGroupUnit**</mark> interface which provides a reference to the selectable group to which each individual unit belongs.

* **Group** reference must be set for system to be able to match units and their groups together. This can be done within the **Editor** or dynamically using `SetGroup` method on group unit component.
* As long as group reference is present, unit will automatically be added or removed from the **group**. There should be no need to manually modify it's list.

  <figure><img src="https://425343605-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fml7vS0D5xN2Q8jQMEmBv%2Fuploads%2FiNZOP0RoFWekeclCpQZ8%2Fimage.png?alt=media&#x26;token=ebe0c737-db47-472f-9c36-c980b96d1fbe" alt=""><figcaption><p>Selectable group unit component</p></figcaption></figure>

<mark style="color:blue;">**SelectableGroup**</mark> has again all the properties already present on <mark style="color:blue;">**SelectableUnit**</mark>**. Additionally it implements&#x20;**<mark style="color:blue;">**ISelectableGroup**</mark> and additionally provides a list of units within the group.

* **Group units** is a dynamic list of units within the group.
* **Destroy group when emptied** flag will specify if group itself should be destroyed when the last unit from it's list is removed. Group component will be disabled if this is set to `false`.
* **OnAllGroupUnitsRemoved** is Unity Event invoked when all units were removed from the list.
* **Center selection indicator** specifies if the indicator is updated every frame (when selected or highlighted) to the calculated center of its unit to be used as some floating GUI.

<figure><img src="https://425343605-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fml7vS0D5xN2Q8jQMEmBv%2Fuploads%2FlyefZ580RouXruQkRKZL%2Fimage.png?alt=media&#x26;token=fd589ba6-839f-4296-beaf-edb3d420312e" alt=""><figcaption><p>Selectable group component</p></figcaption></figure>

## Customisation

Communication between units and selection system is done with <mark style="color:blue;">**ISelectable**</mark>. The same as group components, these interfaces are the extension of <mark style="color:blue;">**ISelectable**</mark>. <mark style="color:blue;">**ISelectableGroup**</mark> and <mark style="color:blue;">**ISelectableGroupUnit**</mark> can be used to completely customise behaviour with your own implementations that work with the selection system.&#x20;

Group example:

```csharp
class MyGroup : MonoBehaviour, ISelectableGroup // ISelectableGroup is key here
{
    public List<ISelectableGroupUnit> GroupUnits { get; private set; } = new();

    public bool IsSelected { get; private set; } = false;

    public bool IsHighlighted { get; private set; } = false;

    public void RemoveGroupUnit(ISelectableGroupUnit groupUnit)
        => GroupUnits.Remove(groupUnit);

    public void AddGroupUnit(ISelectableGroupUnit groupUnit)
        => GroupUnits.Add(groupUnit);

    public void Select()
    {
        // Update all units states and their visuals if selecting a group
        // should show selectors on all its units.
        IsSelected = true;
    }

    public void Deselect()
    {
        IsSelected = false;

        // Update...
    }

    public void Highlight()
    {
        IsHighlighted = true;

        // Update
    }

    public void Unhighlight()
    {
        IsHighlighted = false;

        // Update
    }
}
```

Group Unit example:

```csharp
class MyGroupUnit : MonoBehaviour, ISelectableGroupUnit // ISelectableGroupUnit is key here
{
    public bool IsSelected { get; private set; } = false;

    public bool IsHighlighted { get; private set; } = false;

    // Manage this reference, it is used for matching unit to the group.
    public ISelectableGroup Group { get; private set; } = null;

    public void Select()
    {
        // Update all units states and their visuals if selecting a group
        // should show selectors on all its units.
        IsSelected = true;
    }

    public void Deselect()
    {
        IsSelected = false;

        // Update...
    }

    public void Highlight()
    {
        IsHighlighted = true;

        // Update
    }

    public void Unhighlight()
    {
        IsHighlighted = false;

        // Update
    }

    public void SetGroup(ISelectableGroup group)
    {
        Group = group;

        // Add unit to the group if it is not present yet.
    }
}
```
