> 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/world-map/world-map-ui-manager.md).

# World Map UI (Manager)

### Overview

**WorldMapUI** is a full-screen map overlay that lets players explore the entire game world at once. It renders a pannable, zoomable map — either from a static pre-baked texture or a live orthographic camera — and layers on POI icons, quest objective path lines, player-placed waypoints, and a current location name display. It integrates with **WorldMapTooltip** and **WorldMapFastTravel** for POI inspection and teleportation, and with **WorldMapFogOfWar** for progressive map reveal.

Opening the map is blocked during active dialogue. The Canvas component is enabled and disabled (not the GameObject) so the component's `Update` loop continues running while the map is closed, keeping input detection alive. All animations — open/close fade and smooth pan — use `Time.unscaledTime` so they work correctly when the game is paused.

***

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

### Properties

**Map Settings**

| Property             | Type                 | Default        | Description                                                                                                                                      |
| -------------------- | -------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Auto Find Player** | Bool                 | `true`         | Locates the player by `"Player"` tag at Start if **Player Transform** is empty.                                                                  |
| **Player Transform** | `TransformReference` | Auto           | The player Transform used for the indicator position and centering on open.                                                                      |
| **Auto Find Camera** | Bool                 | `true`         | Locates `Camera.main` at Start if **Camera Transform** is empty.                                                                                 |
| **Camera Transform** | `TransformReference` | Auto           | The main gameplay camera. Used internally — not for map rendering.                                                                               |
| **World Size**       | `Vector2`            | `(1000, 1000)` | Total world extent: `X` = east–west width (world X axis), `Y` = north–south depth (world Z axis). **Must match MinimapUI's World Size exactly.** |
| **World Center**     | `Vector2`            | `(0, 0)`       | XZ centre of the map texture: `X` = world X centre, `Y` = world Z centre (not height). **Must match MinimapUI's World Center exactly.**          |

**Auto-Detect World Bounds** *(Inspector button, edit mode only)*

Scans all Unity `Terrain` objects in the scene and computes **World Size**, **World Center**, and **Camera Height** automatically. Falls back to a manually assigned **Fallback Source** GameObject (uses its Collider, or Renderer bounds if no Collider). Also adjusts the WorldMapCamera's far clip plane to `cameraHeight + 100` units. Fires an Undo-safe write to all three properties and shows a summary dialog. A fallback source is only needed when no Terrain is present.

***

**Map Rendering**

The World Map supports the same two rendering modes as the MinimapUI. If both are configured, camera rendering takes priority.

**Option 1 — Static Map Texture**

| Property               | Type        | Description                                                                                              |
| ---------------------- | ----------- | -------------------------------------------------------------------------------------------------------- |
| **Map Image**          | `RawImage`  | The RawImage that displays the map texture. Required for both modes.                                     |
| **Static Map Texture** | `Texture2D` | Pre-baked overhead map image. Panning and zooming are handled purely in UI space by moving `mapContent`. |

**Option 2 — Camera-Based Rendering**

| Property             | Type                 | Description                                                                                                                                                                                                                                                                                                                                              |
| -------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **World Map Camera** | `TransformReference` | A dedicated orthographic camera. At Start, it is configured automatically: `orthographic = true`, rotated `(90°, 0°, 0°)`, `orthographicSize = worldSize.Y / 2`, `aspect = worldSize.X / worldSize.Y`, positioned at `(worldCenter.X, cameraBaseHeight, worldCenter.Y)`. The Camera *component* (not the GameObject) is disabled when the map is closed. |
| **Render Texture**   | `RenderTexture`      | The RenderTexture the camera renders into. Assigned to `mapImage.texture` at Start.                                                                                                                                                                                                                                                                      |
| **Camera Height**    | Float                | The Y position of the world map camera. Must be above your terrain's highest point. Auto-populated by the **Auto-Detect** button.                                                                                                                                                                                                                        |

> Unlike MinimapUI's live camera (which follows the player), the WorldMapUI camera is **fixed** over the entire world. All panning and zooming are handled in UI space — `mapContent.anchoredPosition` and `mapContent.localScale` — not by moving the camera.

***

**UI References**

| Property                  | Type              | Description                                                                                                                                         |
| ------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **World Map Canvas**      | `Canvas`          | The full-screen overlay Canvas. Enabled/disabled on open/close rather than activating/deactivating the GameObject, keeping the Update loop running. |
| **Map Container**         | `RectTransform`   | The masked viewport. Pan clamping is calculated relative to this rect's size.                                                                       |
| **Map Content**           | `RectTransform`   | The inner content that is panned (`anchoredPosition`) and zoomed (`localScale`). Contains the MapImage, icons, and path dots.                       |
| **Player Indicator**      | `RectTransform`   | Positioned each frame using `WorldToMapPosition(playerPos)` and rotated to match the player's world Y angle.                                        |
| **Canvas Group**          | `CanvasGroup`     | Drives the open/close fade animation. Also controls `blocksRaycasts` and `interactable` so the map is non-interactive while closed.                 |
| **Icon Container**        | `RectTransform`   | Parent for all pooled POI icon instances.                                                                                                           |
| **Path Container**        | `RectTransform`   | Parent for the 100 pre-created path dot instances.                                                                                                  |
| **Current Location Text** | `TextMeshProUGUI` | Displays the name of the player's current location (from LocationManager). Hidden when the player is not inside any named area.                     |

***

**Input**

| Property              | Type      | Default | Description                                                                                                                                          |
| --------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open Key**          | `KeyCode` | `M`     | Keyboard key that toggles the map. Suppressed while the **WaypointPickerUI** is open (to allow typing). Blocked from opening during active dialogue. |
| **Close on Escape**   | Bool      | `true`  | Pressing `Escape` while the map is open calls `CloseMap()`.                                                                                          |
| **Input Action Name** | String    | `""`    | Optional Unity Input System action name. Leave empty to use the KeyCode only.                                                                        |

***

**Pan & Zoom**

| Property                | Type  | Default | Description                                                                                                           |
| ----------------------- | ----- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| **Pan Speed**           | Float | `500`   | Units per second for WASD/arrow key panning. Divided by current zoom so panning feels consistent at all zoom levels.  |
| **Zoom Speed**          | Float | `0.1`   | Zoom delta per mouse wheel tick.                                                                                      |
| **Min Zoom**            | Float | `0.5`   | Minimum allowed zoom level.                                                                                           |
| **Max Zoom**            | Float | `4.0`   | Maximum allowed zoom level.                                                                                           |
| **Default Zoom**        | Float | `1.0`   | Zoom level applied each time the map opens.                                                                           |
| **Pan With WASD**       | Bool  | `true`  | Enables panning with WASD and arrow keys. Blocked while WaypointPickerUI is open.                                     |
| **Pan With Click Drag** | Bool  | `true`  | Enables panning by clicking and dragging the map. Uses a 5px movement threshold to distinguish drags from clicks.     |
| **Mouse Wheel Zoom**    | Bool  | `true`  | Enables zooming with the scroll wheel. Zooms toward the cursor position — the map point under the cursor stays fixed. |

**Pan clamping:** The pan offset is clamped so `mapContent` cannot be dragged beyond its edges. Maximum pan = `(scaledContentSize - containerSize) / 2`. At zoom = 1 where content exactly fills the container, pan is locked to `(0, 0)`.

**Smooth pan:** `CenterOnPlayer()` and `CenterOnPosition()` animate the pan using `SmoothStep` ease-in/out over `panAnimationDuration` seconds (default `0.2s`) using unscaled time. Any WASD or drag input cancels the coroutine immediately.

***

**Game Pause**

| Property                 | Type          | Default | Description                                                                                                                                               |
| ------------------------ | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Pause Game When Open** | Bool          | `true`  | Sets `Time.timeScale = 0` while the map is open. The previous time scale is stored and restored on close.                                                 |
| **Slow Time When Open**  | Bool          | `false` | Alternative to full pause. Sets `Time.timeScale` to **Slow Time Scale** instead. Mutually exclusive with **Pause Game When Open** (pause takes priority). |
| **Slow Time Scale**      | Float *(0–1)* | `0.1`   | The time scale used when **Slow Time When Open** is active.                                                                                               |

***

**Animation**

| Property                     | Type  | Default | Description                                                                                                                              |
| ---------------------------- | ----- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Open Animation Duration**  | Float | `0.3`   | Seconds for the `CanvasGroup.alpha` fade from `0` to `1` on open. Uses `unscaledDeltaTime`.                                              |
| **Close Animation Duration** | Float | `0.2`   | Seconds for the fade from `1` to `0` on close before `FinalizeClose()` is called. Uses `unscaledDeltaTime`.                              |
| **Pan Animation Duration**   | Float | `0.2`   | Seconds for the smooth-pan SmoothStep animation when `CenterOnPlayer()` or `CenterOnPosition()` is called. Set to `0` to snap instantly. |

***

**POI Display**

| Property                           | Type         | Default | Description                                                                                                             |
| ---------------------------------- | ------------ | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| **POI Icon Prefab**                | `GameObject` | None    | Prefab for map markers. Must have an `Image` component. An optional `TextMeshProUGUI` child is used for the name label. |
| **Max Icons**                      | Int          | `100`   | Hard cap on visible POI icons. A pool of this many instances is created at Start.                                       |
| **Respect POI Filters**            | Bool         | `true`  | Passes each POI through `POIFilterManager.ShouldDisplayPOI()` before showing it.                                        |
| **Scale With Zoom**                | Bool         | `true`  | Scales icons by `baseIconScale / currentZoom`, keeping them a constant screen size regardless of zoom level.            |
| **Base Icon Scale**                | Float        | `1.0`   | Base multiplier for all POI icon sizes.                                                                                 |
| **Selected Icon Scale Multiplier** | Float        | `1.4`   | Additional scale applied to the currently selected icon.                                                                |

**Name labels** are enabled when: zoom ≥ 1.5 **or** the mouse is hovering over the icon **or** the icon is selected.

**Fog of War exceptions:** `CustomWaypoint` instances and POIs with a `linkedObjectiveId` always bypass fog visibility checks — they are always shown even in unexplored areas.

***

**Quest Integration**

| Property                           | Type  | Default | Description                                                                                                                           |
| ---------------------------------- | ----- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Show Quest Objective Markers**   | Bool  | `true`  | Enables display of POI markers linked to active quest objectives.                                                                     |
| **Highlight Tracked Objective**    | Bool  | `true`  | Applies a pulsing colour override to the POI icon of the currently tracked objective.                                                 |
| **Tracked Objective Color**        | Color | Yellow  | Base colour of the tracked objective pulse.                                                                                           |
| **Tracked Pulse Speed**            | Float | `2`     | Speed of the sine-wave pulse: `color * (1 + sin(unscaledTime * speed) * 0.3)`. Icon is also scaled to 130% of its base size.          |
| **Show Path To Tracked Objective** | Bool  | `true`  | Draws a dotted line from the player's map position to each tracked quest objective.                                                   |
| **Path Color**                     | Color | Yellow  | Colour of quest objective path dots.                                                                                                  |
| **Path Dot Size**                  | Float | `4`     | Pixel size of each dot. Scaled by `1 / currentZoom` when **Scale With Zoom** is enabled.                                              |
| **Path Dot Spacing**               | Float | `15`    | Pixel distance between dot centres along the path.                                                                                    |
| **Show Waypoint Path**             | Bool  | `true`  | Draws a second path to the active navigation waypoint in a distinct colour.                                                           |
| **Waypoint Path Colour**           | Color | Cyan    | Colour of the waypoint navigation path.                                                                                               |
| **Animate Path Dots**              | Bool  | `true`  | Advances `pathAnimationOffset` by `unscaledDeltaTime * pathAnimationSpeed` each frame, making dots appear to march toward the target. |
| **Animation Speed**                | Float | `20`    | Dots per second the pattern scrolls. Matches MinimapUI's default for visual consistency.                                              |

> Path drawing on the world map uses **straight lines only** — no NavMesh calculation. The world map is zoomed out enough that NavMesh paths would be too noisy to be useful.

***

**Waypoint Placement**

| Property                      | Type               | Default           | Description                                                                                                                                                                                          |
| ----------------------------- | ------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Enable Waypoint Placement** | Bool               | `true`            | Allows players to click on the map to place a custom navigation waypoint.                                                                                                                            |
| **Mouse Button**              | Int                | `1` (right-click) | Mouse button index: `0` = left, `1` = right, `2` = middle.                                                                                                                                           |
| **Picker UI**                 | `WaypointPickerUI` | Auto-found        | Optional panel for choosing the waypoint's icon and name before confirming. If unassigned, waypoints are placed instantly on click and `OnWaypointPlacedFromMap` fires immediately.                  |
| **Snap to Ground**            | Bool               | `true`            | Fires a downward `Physics.Raycast` from `(x, groundRaycastHeight, z)` to find the actual ground Y at the clicked XZ. Prevents waypoints spawning at Y=0 on non-flat worlds.                          |
| **Ground Layer Mask**         | LayerMask          | Everything        | Layers considered ground for the snap raycast. Narrow this to your terrain/floor layer to avoid hitting triggers or water.                                                                           |
| **Raycast Height**            | Float              | `500`             | Height above the XZ point from which the downward ray fires. Must exceed your world's highest point.                                                                                                 |
| **Ground Y Offset**           | Float              | `0`               | Extra Y added on top of the sampled ground hit. Set to your ground Y (e.g. `-6.4`) as a direct override if the raycast consistently misses. Enable **Debug Mode** to diagnose misses in the Console. |

**Waypoint placement is blocked when:**

* The pointer is over a `Button`, `Toggle`, or `Scrollbar` UI element.
* `POIManager.CanCreateWaypoint` returns `false`.
* The `WaypointPickerUI` is already open.

***

**Fast Travel**

| Property                     | Type  | Default | Description                                                                                                                                                                       |
| ---------------------------- | ----- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Enable Fast Travel**       | Bool  | `true`  | Master toggle. When `false`, `TryFastTravelToTarget()` returns `false` for all POIs.                                                                                              |
| **Enable Double-Click**      | Bool  | `false` | Double-clicking a POI icon within the time window attempts fast travel directly, bypassing the tooltip. Falls back to opening the tooltip if the POI doesn't support fast travel. |
| **Double-Click Time Window** | Float | `0.3`   | Maximum seconds between two clicks to register as a double-click.                                                                                                                 |

Fast travel requires: `FastTravelEnabled` + the target is a `POIMarker` with `poiData.EnableFastTravel` + the location has been discovered by the `LocationManager`.

***

**Fog of War**

| Property                 | Type               | Description                                                                                                                                                                                        |
| ------------------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fog of War Component** | `WorldMapFogOfWar` | Reference to the optional fog overlay component. Passed `Initialize(this)` when the map opens. POIs that haven't been revealed are hidden unless they are CustomWaypoints or quest-linked markers. |

***

### Events

| Event                       | Signature                     | When It Fires                                                                                                                      |
| --------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **OnMapOpened**             | `UnityEvent`                  | After the map is made visible and `OpenMap()` setup is complete.                                                                   |
| **OnMapClosed**             | `UnityEvent`                  | After `FinalizeClose()` — after the fade and time scale restoration.                                                               |
| **OnWaypointPlacedFromMap** | `UnityEvent<Vector3>`         | When a waypoint is confirmed (immediately if no picker; on picker confirm if picker is assigned). Passes the world-space position. |
| **OnFastTravelRequested**   | `UnityEvent<PointOfInterest>` | When fast travel is initiated to a POI. Fired by the `WorldMapFastTravel` sub-component.                                           |

***

### Public API

| Method / Property                      | Description                                                                                                                                             |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OpenMap()`                            | Opens the map with fade animation, centering on the player. No-op if already open or animating.                                                         |
| `CloseMap()`                           | Closes the map with fade animation. No-op if already closed or animating.                                                                               |
| `CloseMapImmediate()`                  | Closes the map instantly, skipping the fade. Restores `Time.timeScale` immediately.                                                                     |
| `ToggleMap()`                          | Calls `OpenMap()` or `CloseMap()` depending on current state.                                                                                           |
| `CenterOnPlayer()`                     | Smooth-pans the map to centre on the player's current world position.                                                                                   |
| `CenterOnPosition(Vector3)`            | Smooth-pans the map to centre on any world position.                                                                                                    |
| `ZoomIn()`                             | Increments zoom by `zoomSpeed * 2`.                                                                                                                     |
| `ZoomOut()`                            | Decrements zoom by `zoomSpeed * 2`.                                                                                                                     |
| `ResetZoom()`                          | Resets zoom to `defaultZoom`.                                                                                                                           |
| `WorldToMapPosition(Vector3)`          | Converts a world-space position to `mapContent` local position.                                                                                         |
| `MapToWorldPosition(Vector2)`          | Converts a `mapContent` local position back to world space, sampling ground Y.                                                                          |
| `SetCanvasVisibleForFade(bool, Image)` | Used by the fast travel system to keep the Canvas alive for a screen-fade overlay while hiding all other map UI elements. Pass `false` to restore them. |
| `IsOpen`                               | `bool` — Whether the map is currently open.                                                                                                             |
| `CurrentZoom`                          | `float` — Current zoom level.                                                                                                                           |
| `FastTravelEnabled`                    | `bool` — Whether fast travel is enabled.                                                                                                                |
| `WorldSize`                            | `Vector2` — The configured world size.                                                                                                                  |
| `WorldCenter`                          | `Vector2` — The configured world XZ centre.                                                                                                             |

***

### Inspector Testing Tools *(Play Mode Only)*

| Button               | Action                    |
| -------------------- | ------------------------- |
| **Open Map**         | Calls `OpenMap()`.        |
| **Close Map**        | Calls `CloseMap()`.       |
| **Center on Player** | Calls `CenterOnPlayer()`. |
| **Reset Zoom**       | Calls `ResetZoom()`.      |

The Runtime Status foldout also displays **Is Open** and **Current Zoom** live.

***

### Usage Tips

* **World Size / World Center must match** — the MinimapUI and WorldMapUI use the same coordinate conversion formula. If these values differ between the two components, POI icons will appear at the wrong positions on one of them. Use the **Auto-Detect World Bounds** button on the WorldMapUI to populate all three values, then copy them to the MinimapUI manually.
* **Camera vs static texture** — the world map camera renders the entire world at once into a fixed texture. This is more expensive than MinimapUI's player-following camera. For large worlds, a pre-baked static texture is the recommended choice — it has zero per-frame rendering cost.
* **Camera height** — set `Camera Height` to at least 50 units above your tallest terrain point. The Auto-Detect button sets it to `maxTerrainHeight + 50` and also adjusts the camera's far clip plane to `cameraHeight + 100`.
* **Waypoint ground snapping** — if waypoints consistently spawn at the wrong height, enable **Debug Mode** and check the Console when clicking the map. The `SampleGroundHeight` logs show the ray origin, hit name, and final Y. If the ray misses entirely, set **Ground Y Offset** to your ground's Y position as a direct override, and narrow **Ground Layer Mask** to your terrain/floor layer.
* **Double-click fast travel** — keep the time window short (`0.2–0.3s`). A longer window makes it feel like normal clicks are accidentally triggering fast travel. Single-click → tooltip + fast travel button is the safer default workflow.
* **Time scale restoration** — if the game freezes after fast travel, check that `CloseMapImmediate()` is being called before the fast travel teleport. `CloseMap()` with an animation can delay the `Time.timeScale` restoration until after the fade.
* **WaypointPickerUI** — this panel is auto-found via `GetComponentInChildren` in Awake. It does not need to be assigned manually as long as it exists anywhere inside the WorldMapUI hierarchy.
