> For the complete documentation index, see [llms.txt](https://solo-player.gitbook.io/most-in-one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://solo-player.gitbook.io/most-in-one/most-systems/most-aim.md).

# MOST Aim

A powerful and flexible aiming and trajectory visualization system. It handles player input to calculate aim direction, rotates the character model, and draws a visual guide (ray, arc, or shape) to the target. It supports multiple aiming modes — from simple direct rays to parabolic throws — plus auto-aim targeting.

{% hint style="info" %}

* **This System requires an Input Controller to receive commands** (e.g., MOST Controller or any custom input system).
* All input examples in MOST IN ONE use MOST Controller, but the system is designed to be easily adapted to any input source.
* You will find the "Input Getter" section inside `MOST_Aim.cs` containing all functions that receive commands.
  {% endhint %}

### Quick Start

1. **Add Component**: Add the `MOST_Aim` component to a GameObject in your scene (typically the player character).
2. **Assign Key References**: In the Inspector, assign the `RotateModel` (the character's visual transform) and `StartPosition` (where rays/throws originate).
3. **Choose an Aim Type**: Select a mode from the **Aim Type** dropdown (e.g., `DirectRay`, `Throw`, `SemiCircle`). The inspector adapts, showing only relevant settings for the chosen mode.
4. **Connect Input**: Call the appropriate input functions from your controller script (see the **Input Getter** section below) to start, update, and stop aiming.
5. **Subscribe to Events**: Use the `OnAimming`, `OnRelease`, or `OnReleaseThrow` UnityEvents in the Inspector to trigger your game logic (e.g., shooting a projectile, playing an animation).

### Concepts & Terminology

**Aim Type**: The core mode of the system, dictating both the aiming logic and the visual representation.

* **`NoRay`**: No visual ray is drawn. The system only handles rotation.
* **`Throw`**: Calculates a parabolic trajectory for lobbing objects. Uses a `LineRenderer`.
* **`DirectSquare`**: Draws a thick, rectangular ray that can reflect off surfaces. Uses `Mesh` generation.
* **`DirectRay`**: A standard, thin ray that can reflect off surfaces. Uses a `LineRenderer`.
* **`SemiCircle`**: Draws a semi-circular or full-circle area in front of the character. Can be rendered as a filled shape or an outline.

**Rotation State**: Controls when the character model (`RotateModel`) rotates to face the aim direction. Options include `NoRotation`, `ApplyOnDirectionUpdate`, and `ApplyOnRelease`.

**Rotation Way**: Defines how the model rotates. `InstantLookAt` snaps the rotation, while `WithSpeed` smoothly interpolates using `RotateSpeed`.

### Key Features

* **Multiple Aim Types** — Direct rays, reflective rays, thick square rays, parabolic throw arcs, and area-based semi-circles.
* **Flexible Input** — Input-agnostic design; drive the system from any controller (MOST Controller, Unity's Input System, or custom input).
* **Auto-Aim** — Optional targeting system that can pull targets from a `MOST_Detector` or a manually populated list.
* **Rotation Control** — Choose when and how the character model rotates to face the aim direction.
* **Animation Integration** — Optional hooks for setting Animator parameters (aim bool, release bool, aim direction float).
* **Delay & Timing Control** — Configurable delays for start, between calls, and release.
* **Event-Driven** — UnityEvents for aim updates, release, and throw-specific releases.

### Configuration Overview

Settings are grouped into clearly labeled sections in the Inspector:

* **Enable State** — Runtime enabled status and whether to enable on start.
* **Rotation Settings** — How and when to rotate the character model.
* **AutoAim Settings** — Optional automatic target acquisition and detector linkage.
* **Drawing Settings** — Aim type and all visual tuning (materials, widths, segments, reflection counts, throw arc parameters, semi-circle geometry, etc.). Visible fields adapt based on the selected `AimType`.
* **Delay Section** — Timing controls for aim start, between-call interval, and release.
* **Animation Settings** — Optional Animator parameter control.
* **Events Section** — UnityEvents for aim updates and releases.

### Input Getter (Required)

The system is input-agnostic. You must call these functions from your input controller script to drive the aiming logic.

#### Starting Aim

Call **one** of these functions to begin the aiming process.

```csharp
// Call this if the input doesn't provide a direction yet.
// The aim will start in the character's current facing direction.
// Ideal for a simple "touch to aim" input.
MOST_Aim.OnInputDetected();

// Call this if the input already provides a direction.
// The aim will start toward the provided direction.
// Ideal for a joystick that has been moved past a deadzone.
MOST_Aim.OnExceedMinRange(Vector2 direction);
```

#### Updating Direction

Call one of these functions every frame (or whenever the input direction changes) while aiming.

```csharp
// Uses the absolute direction of the input. The magnitude of the direction is ignored.
MOST_Aim.OnInputUpdated(Vector2 direction);

// Uses the raw input, preserving its magnitude (0 to 1).
// Useful for mechanics where the aim distance depends on how far the joystick is pushed.
MOST_Aim.OnRawValueUpdated(Vector2 direction);
```

#### Stopping Aim

```csharp
// Call this to stop aiming and trigger the release logic.
// The optional `exceeded` parameter is typically used in conjunction with delta-scaled inputs.
// Default value is false.
MOST_Aim.OnInputReleased(bool exceeded = false);
```

### Auto-Aim

The system features a built-in auto-aim that can target objects from a list.

* **EnableAutoAim**: A public boolean to toggle the feature.
* **`AutoAimControl(bool enable)`**: An API method to toggle auto-aim at runtime.
* **AimDetector**: An optional `MOST_Detector` reference. If assigned, it automatically populates the `OnRangeEnemyList` with detected objects.
* If no `AimDetector` is used, you must manually populate `OnRangeEnemyList`.
* The system aims at the first object in the list.
* **`AutoSend`**: When `true`, auto-aim updates the aim direction and fires `OnAimming` events automatically, without requiring manual input release. When `false`, auto-aim is triggered via the `AutoAim()` method on input release.

### Events

* **`OnAimming(Vector2 direction)`** — Fired repeatedly while aiming. The `Vector2` is the current aim direction (XZ plane).
* **`OnRelease(Vector2 direction)`** — Fired on release for non-Throw modes.
* **`OnReleaseThrow(float heightScale, float computedHeight, Vector3 hitPoint)`** — Fired on release for Throw mode.

***

<h3 align="center">API</h3>

These methods and properties are intended for use from other scripts.

#### Core Control

```csharp
// Enables or disables the entire aiming system.
aimSystem.EnableState(bool enable);

// Enables or disables the auto-aim feature.
aimSystem.AutoAimControl(bool enable);

// Manually triggers the auto-aim sequence (useful if AutoSend is false).
aimSystem.AutoAim();

// Temporarily disables the system's output for a specified duration.
// Useful for stuns, cooldowns, or disarmed states.
aimSystem.DisableOutput(float time);
```

#### Visual Control

```csharp
// Forces an immediate update of the visual ray/trajectory.
aimSystem.CreateRay();

// Clears the currently drawn ray/trajectory.
aimSystem.Clear();
```

#### Input (Required)

See the **Input Getter** section above for details.

```csharp
aimSystem.OnInputDetected();
aimSystem.OnExceedMinRange(Vector2 direction);
aimSystem.OnInputUpdated(Vector2 direction);
aimSystem.OnRawValueUpdated(Vector2 direction);
aimSystem.OnInputReleased(bool exceeded = false);
```

#### Read-Only State

```csharp
// Returns true if the system is currently enabled.
bool isEnabled = aimSystem.Enable;
```

#### Events

```csharp
aimSystem.OnAimming.AddListener(OnAimUpdated);      // Vector2 direction
aimSystem.OnRelease.AddListener(OnAimReleased);     // Vector2 direction
aimSystem.OnReleaseThrow.AddListener(OnThrow);      // float, float, Vector3
```

Remove listeners with `RemoveListener` when no longer needed (e.g., in `OnDisable`).

### Runtime-Controllable Properties

The following public properties are safe to modify at runtime and take effect immediately. They are useful for dynamic gameplay scenarios such as weapon switching, power-ups, mode changes, or adapting to player state.

{% hint style="info" %}
`OnRangeEnemyList` is read-only from the API's perspective — it is managed internally by the system when a detector is assigned. If you want manual control, assign your own list values before aiming.
{% endhint %}

```csharp
// ============================================================
// Runtime-Controllable Properties
// ------------------------------------------------------------
// These public properties are safe to modify at runtime and
// take effect on the next aim update. Useful for weapon
// switching, power-ups, mode changes, and player state.
// ============================================================

// --- Rotation Control ---
aimSystem.RotationState           = MOST_Aim.RotationSettings.ApplyOnDirectionUpdate;
aimSystem.RotationWay             = MOST_Aim.RotationType.InstantLookAt;
aimSystem.RotateModel             = playerModel;         // Transform to rotate
aimSystem.RotateSpeed             = 720f;                // deg/sec for WithSpeed
aimSystem.MoveSystem              = moveSystem;          // Optional movement system
aimSystem.FixDirectionOnCameraAngle = true;              // Align input to camera Y-angle

// --- Auto-Aim Control ---
aimSystem.EnableAutoAim   = true;
aimSystem.AutoSend        = true;                        // Fire OnAimming automatically
aimSystem.AimDetector     = detector;                    // Optional MOST_Detector
aimSystem.CalculationPoint = muzzlePoint;                // Transform for aim calc

// --- Aim Mode & Visuals (mode-specific) ---
aimSystem.Type             = MOST_Aim.AimType.DirectRay; // Change aim mode at runtime
aimSystem.StartPosition    = muzzlePoint;                // Origin of the ray/throw
aimSystem.RayMaterial      = laserMaterial;
aimSystem.RayColor         = Color.red;
aimSystem.DrawSegments     = 24;

// --- Ray Modes (DirectRay / DirectSquare) ---
aimSystem.ReflectedLayers    = LayerMask.GetMask("Walls");
aimSystem.BlockLayers        = LayerMask.GetMask("Enemies", "Walls");
aimSystem.NumberOfReflections = 3;
aimSystem.MaxLenght          = 15f;
aimSystem.RayWidth           = 0.5f;

// --- Throw Mode ---
aimSystem.MaxDistance    = 12f;
aimSystem.TargetInYAxis  = 0.01f;
aimSystem.MaxHight       = 10f;
aimSystem.DynamicHight   = true;
aimSystem.DrawWidth      = widthCurve;
aimSystem.HitPointSpot   = impactMarkerPrefab;

// --- SemiCircle Mode ---
aimSystem.DrawType         = MOST_Aim.DrawingType.Outline;
aimSystem.Radius           = 6f;
aimSystem.AngleScale       = 180f;
aimSystem.InnerCut         = 2f;
aimSystem.TextureScale     = 2f;
aimSystem.SideOffsetDistance = 0f;

// --- Timing ---
aimSystem.StartAimDelay             = 0.1f;
aimSystem.DelayBetweenOnAimCalls    = 0.05f;
aimSystem.OnReleaseDelay            = 0.1f;

// --- Animation ---
aimSystem.EnableAnimationControl = true;
aimSystem.AnimationControl       = animator;
aimSystem.OnAim_Bool             = "IsAiming";
aimSystem.OnRelease_Bool         = "IsReleasing";
aimSystem.AimDirection_Float     = "AimAngle";
```

{% hint style="warning" %}
**Do not reassign the UnityEvent fields** (`OnAimming`, `OnRelease`, `OnReleaseThrow`) at runtime — that will wipe out any listeners assigned in the Inspector. Always use `AddListener` / `RemoveListener` instead.
{% endhint %}

{% hint style="success" %}
Changing `Type` at runtime immediately switches the aim mode and visual representation. Make sure the required references for the new mode (e.g., `RayMaterial` for ray modes) are assigned before switching, or the visuals may fail to render.
{% endhint %}

### Notes & Tips

* If `FixDirectionOnCameraAngle` is enabled, the aim direction is interpreted relative to the main camera's Y-angle. This is ideal for third-person and top-down games.
* Use `OnInputDetected()` when the input starts without a direction (e.g., a simple button press). Use `OnExceedMinRange(direction)` for joysticks after the deadzone is passed.
* Choose between `OnInputUpdated` (direction-only, magnitude ignored) and `OnRawValueUpdated` (magnitude preserved) depending on whether your gameplay uses aim distance from the joystick magnitude (common in Throw mode).
* `DisableOutput(time)` is convenient for cooldowns or stuns — the system continues to exist but suppresses drawing and release behavior for the given duration.
* For a purely visual aim without rotation control, set `RotationState` to `NoRotation`.

### Example: Connecting a Controller

This snippet shows how to connect a hypothetical joystick input to the `MOST_Aim` system.

```csharp
using UnityEngine;

public class AimInputBridge : MonoBehaviour
{
    public MOST_Aim aimSystem;
    public Joystick inputJoystick; // Your input source

    void Update()
    {
        if (inputJoystick.IsPressed)
        {
            if (inputJoystick.WasJustPressed)
                aimSystem.OnInputDetected(); // Start aiming in current facing

            if (inputJoystick.Direction.magnitude > 0.1f)
                aimSystem.OnInputUpdated(inputJoystick.Direction);
        }

        if (inputJoystick.WasJustReleased)
            aimSystem.OnInputReleased(false);
    }
}
```

***

**Note on Input:** The system is designed to be decoupled from input. You can use `MOST_Controller`, Unity's new Input System, or a custom input solution. The key is to call the `OnInput...` methods from your input handler to drive `MOST_Aim`.
