> For the complete documentation index, see [llms.txt](https://infinitypbr.gitbook.io/magic-pig-games/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infinitypbr.gitbook.io/magic-pig-games/other/locks-lock-picking-and-ciphers-skyrim-style-lock-picking/lock-picking-quick-start.md).

# Lock Picking Quick Start

v1.0

{% stepper %}
{% step %}

### Step 1 — Add a prefab to your scene

All ready-to-use prefabs are in the `_Prefabs` folder. Drag one into your scene:

| Prefab                                           | Lock type                              | Script       |
| ------------------------------------------------ | -------------------------------------- | ------------ |
| **Lockset**                                      | Pick-and-turn keyhole (Skyrim-style)   | `Keyhole`    |
| **Cipher**, **Cipher Variant (9/12/18 Symbols)** | Combination wheel lock                 | `Cipher`     |
| **Button**                                       | Pressable button                       | `LockButton` |
| **Lock1**, **Lock2**, **Lock3**                  | Standalone lock body meshes (no logic) | —            |
| **Padlock1**                                     | Padlock mesh used by Lockset           | —            |

The prefab arrives pre-wired — all internal references (keyhole mesh, lock pick, animators, audio objects) are already connected. You do not need to touch the **Plumbing** section of the Inspector unless you are building a custom lock from scratch.
{% endstep %}

{% step %}

### Step 2 — Wire up player input

None of the lock scripts poll input themselves — you pass values in from your own input script each frame. This keeps the locks compatible with any input system (Unity Input System, legacy Input, Rewired, gamepad, touch, etc.).

#### Keyhole (pick-and-turn)

Get a reference to the `Keyhole` component and set two floats every frame:

```csharp
using Lockpicking;
using UnityEngine;

public class MyLockControls : MonoBehaviour
{
    public Keyhole keyhole;

    void Update()
    {
        keyhole.openPressure     = 0f;
        keyhole.lockpickPressure = 0f;

        if (Input.GetKey(KeyCode.LeftArrow))  keyhole.lockpickPressure = -1f;
        if (Input.GetKey(KeyCode.RightArrow)) keyhole.lockpickPressure =  1f;
        if (Input.GetKey(KeyCode.Space))      keyhole.openPressure     =  1f;
    }
}
```

* `lockpickPressure` — moves the pick left/right (`-1` to `1`)
* `openPressure` — applies turning pressure to try to open the lock (`0` to `1`)

{% hint style="info" %}
See the **Keyhole** page for full input details, analogue/gamepad mapping, and difficulty settings.
{% endhint %}

#### Cipher (combination wheels)

Call these methods from your input script:

```csharp
using Lockpicking;
using UnityEngine;

public class MyCipherControls : MonoBehaviour
{
    public Cipher cipher;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
            cipher.SelectWheel(cipher.NextWheelIndex);

        if (Input.GetKey(KeyCode.UpArrow))    cipher.MoveActiveWheel(-1);
        if (Input.GetKey(KeyCode.DownArrow))  cipher.MoveActiveWheel( 1);

        if (Input.GetKeyDown(KeyCode.Return)) cipher.TryOpen();
    }
}
```

* `SelectWheel(index)` — choose which wheel the player is controlling
* `MoveActiveWheel(-1 / 1)` — rotate the selected wheel up or down
* `TryOpen()` — attempt to open; plays a shake and does nothing if the combination is wrong

{% hint style="info" %}
See the **Cipher** page for per-wheel input, analogue mapping, and difficulty settings.
{% endhint %}

#### LockButton

```csharp
public class MyButtonControls : MonoBehaviour
{
    public LockButton lockButton;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
            lockButton.ToggleButton();
    }
}
```

{% hint style="info" %}
See the **LockButton** page for forcing specific states and event details.
{% endhint %}
{% endstep %}

{% step %}

### Step 3 — React to lock events

Each lock exposes UnityEvents you can hook up **in the Inspector** or **in code**. No polling required.

#### In the Inspector

1. Select the lock GameObject.
2. Find the event in the Inspector (e.g. **Lock Open Events**).
3. Click **+**, drag in the target GameObject, and choose the method to call.

This is the fastest option and requires no code. Common uses:

* **Lock Open Events → Door.Open()** — open a door when the lock is picked
* **Lock Open Events → Canvas.SetActive(false)** — hide the lock UI
* **Lockpick Broke Events → UIManager.ShowBrokeMessage()** — show a "pick broke" prompt
* **Lock Failed Events → AudioSource.Play()** — play a failure sound

#### In code

```csharp
using Lockpicking;
using UnityEngine;

public class MyLockListener : MonoBehaviour
{
    public Keyhole keyhole;
    public Cipher  cipher;

    void OnEnable()
    {
        // Keyhole events
        keyhole.lockOpenEvents.AddListener(OnLockOpened);
        keyhole.lockpickBrokeEvents.AddListener(OnPickBroke);
        keyhole.lockFailedEvents.AddListener(OnLockFailed);

        // Cipher event
        cipher.lockOpenEvents.AddListener(OnLockOpened);
    }

    void OnDisable()
    {
        keyhole.lockOpenEvents.RemoveListener(OnLockOpened);
        keyhole.lockpickBrokeEvents.RemoveListener(OnPickBroke);
        keyhole.lockFailedEvents.RemoveListener(OnLockFailed);
        cipher.lockOpenEvents.RemoveListener(OnLockOpened);
    }

    void OnLockOpened() { /* unlock door, award XP, play fanfare, etc. */ }
    void OnPickBroke()  { /* show "your pick broke" UI, reduce pick count, etc. */ }
    void OnLockFailed() { /* called every frame the player presses in the wrong spot */ }
}
```

{% hint style="info" %}
`lockFailedEvents` fires continuously while the player is applying pressure in the wrong position, not just once. Use it for sustained feedback (e.g. a rumble effect) and guard with a cooldown if you only want a single trigger.
{% endhint %}

#### Available events

| Script           | Event                 | When it fires                                          |
| ---------------- | --------------------- | ------------------------------------------------------ |
| `Keyhole`        | `lockOpenEvents`      | Lock successfully opened                               |
| `Keyhole`        | `lockpickBrokeEvents` | Pick broke after too much failed pressure              |
| `Keyhole`        | `lockFailedEvents`    | Player applying pressure but pick is in wrong position |
| `Cipher`         | `lockOpenEvents`      | All wheels in position and `TryOpen()` called          |
| `LockButton`     | `buttonPressedEvents` | Button pressed down                                    |
| `LockButton`     | `buttonResetEvents`   | Button released / popped back up                       |
| {% endstep %}    |                       |                                                        |
| {% endstepper %} |                       |                                                        |
