> For the complete documentation index, see [llms.txt](https://malbersanimations.gitbook.io/animal-controller/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malbersanimations.gitbook.io/animal-controller/malbers-questforge/npc-speech-bubbles/speech-bubble-manager.md).

# Speech Bubble Manager

### Overview

The **SpeechBubbleManager** is a persistent singleton (`DontDestroyOnLoad`) that must exist in the scene for the bubble system to function. If none is present, one is auto-created at runtime as an empty GameObject — though without a **Default Bubble Prefab** assigned, no bubbles will render.

> Add via **Component menu: `Malbers Quest Forge → Speech Bubble Manager`**

<figure><img src="/files/Hp54GuxQQdkajtpAfzc1" alt=""><figcaption></figcaption></figure>

### **Properties**

**Global Settings**

| Property                | Type             | Default | Description                                                                                                                                      |
| ----------------------- | ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Max Visible Bubbles** | Int *(1–20)*     | `5`     | Hard cap on how many bubbles can be visible simultaneously. When eligible bubble count exceeds this, only the closest N (by distance) are shown. |
| **Update Interval**     | Float *(0.05–1)* | `0.1`   | How often (in seconds) the Manager runs its visibility update pass. Lower values are more responsive but use slightly more CPU.                  |
| **Global Max Distance** | Float            | `50`    | Any bubble beyond this distance is filtered out before the priority sort, regardless of its own activation distance.                             |

**Prioritisation**

| Property                     | Type            | Default | Description                                                                                                                                                                                    |
| ---------------------------- | --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Prioritize by Distance**   | Bool            | `true`  | When `true`, eligible bubbles are sorted by `DistanceToPlayer` ascending before the cap is applied — closest NPCs always win. When `false`, bubbles compete in registration order.             |
| **Priority Update Interval** | Float *(0.1–2)* | `0.2`   | How frequently the Manager re-evaluates which bubbles are in the top N. A requested update (e.g. from dialogue starting) also triggers an immediate re-evaluation regardless of this interval. |

**Object Pooling**

| Property                  | Type         | Default | Description                                                                                                                                 |
| ------------------------- | ------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Enable Pooling**        | Bool         | `true`  | When `true`, bubble UI instances are reused from a pool rather than instantiated/destroyed. Strongly recommended for scenes with many NPCs. |
| **Initial Pool Size**     | Int          | `10`    | Number of bubble instances pre-instantiated at Awake. Set this to at or above **Max Visible Bubbles** to avoid runtime allocations.         |
| **Default Bubble Prefab** | `GameObject` | None    | The prefab instantiated for pooling. Must have a `SpeechBubbleUI` component. Required — no bubbles render without it.                       |

**Performance**

| Property                         | Type  | Default | Description                                                                                 |
| -------------------------------- | ----- | ------- | ------------------------------------------------------------------------------------------- |
| **Use Performance Optimization** | Bool  | `true`  | Reserved flag for disabling all bubble processing when the player is very far from any NPC. |
| **Performance Disable Distance** | Float | `100`   | Distance threshold for the above optimisation.                                              |

### **Manager Public API**

| Method                                   | Description                                                                                                                                                                           |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HideAllBubbles(bool immediate = false)` | Calls `ForceHide()` on every registered bubble. Use for cutscenes, menus, or loading screens.                                                                                         |
| `ShowAllBubbles()`                       | Calls `ReEnableAfterForceHide()` on every registered bubble and requests a visibility update.                                                                                         |
| `RequestVisibilityUpdate()`              | Flags the Manager to run a full visibility update on the next `Update()` tick, bypassing the priority update interval.                                                                |
| `GetVisibleBubbleCount()`                | Returns the count of currently visible bubbles.                                                                                                                                       |
| `CanShowMoreBubbles()`                   | Returns `true` if the visible count is below `maxVisibleBubbles`.                                                                                                                     |
| `GetRegisteredBubbles()`                 | Returns a copy of the full registered bubble list.                                                                                                                                    |
| `GetVisibleBubbles()`                    | Returns a copy of the currently visible bubble list.                                                                                                                                  |
| `GetDebugStats()`                        | Returns a formatted string: registered count, eligible count, visible/max, pooled count, active count. Displayed as an on-screen overlay in Play Mode when **Debug Mode** is enabled. |
