> 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-button.md).

# Lock Button

v1.0

`LockButton` is a toggleable physical button with press/release animations and events.

### Triggering the button from code

```csharp
// Toggle between pressed and released
lockButton.ToggleButton();

// Set a specific state explicitly (true = released/up, false = pressed/down)
lockButton.ToggleButton(true);   // force to "up" state
lockButton.ToggleButton(false);  // force to "pressed/down" state
```

{% hint style="info" %}
`ToggleButton(bool up)` only fires the animation and events if the button is not already in the requested state.
{% endhint %}

### Wiring up player input

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

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

{% hint style="info" %}
`LockButton` already contains a built-in `Update` that listens for `KeyCode.P`. Replace or extend this if you need different input.
{% endhint %}

### Events

```csharp
// Fired when the button is pressed down
lockButton.buttonPressedEvents.AddListener(OnButtonPressed);

// Fired when the button resets (pops back up)
lockButton.buttonResetEvents.AddListener(OnButtonReset);

void OnDestroy()
{
    lockButton.buttonPressedEvents.RemoveListener(OnButtonPressed);
    lockButton.buttonResetEvents.RemoveListener(OnButtonReset);
}
```

A common pattern is to link `buttonPressedEvents` → `Keyhole.ResetLock` or `Cipher.ResetLock` in the Inspector to wire a physical reset button directly to a lock.

## Common Patterns

### Showing a UI prompt when a lock opens

Subscribe to the event in a UI manager:

```csharp
void Start()
{
    keyhole.lockOpenEvents.AddListener(ShowUnlockedUI);
    cipher.lockOpenEvents.AddListener(ShowUnlockedUI);
}

void ShowUnlockedUI()
{
    // Enable your UI panel, play a sound, trigger a cutscene, etc.
}
```

### Scaling difficulty with player skill

```csharp
// Keyhole — give a skilled player a wider angle window
float skillFactor = playerSkill / 100f; // 0–1
float give = Mathf.Lerp(minGive, maxGive, skillFactor);
keyhole.SetLock(Random.Range(minAngle, maxAngle), give, Random.Range(minClose, maxClose));

// Cipher — give a skilled player more tolerance per wheel
cipher.closeEnough = Mathf.Lerp(2f, 8f, skillFactor);
cipher.ResetLock();
```

### Resetting a lock when the player walks away

```csharp
void OnTriggerExit(Collider other)
{
    if (other.CompareTag("Player"))
    {
        keyhole.ResetLock();
        // or
        cipher.ResetLock();
    }
}
```

### Linking a LockButton to a lock reset in the Inspector

In the `LockButton` component on your lock button GameObject:

1. Select the **buttonPressedEvents** field.
2. Click **+** to add a listener.
3. Drag your lock GameObject into the object slot.
4. Choose **Keyhole → ResetLock** (or **Cipher → ResetLock**) from the function dropdown.

No code required.
