> 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/magic-time-local-time-scale/local-time-scale/local-time-scale-scripting.md).

# Local Time Scale Scripting

Check the `LocalTimeScale` class to view all of the methods available.

## Getting the Time Values

The `LocalTimeScale` will have its own time values similar to the `Time` class. You can get these using `DeltaTime`, `UnscaledDeltaTime`, and `FixedDeltaTime`.

```csharp
LocalTimeScale localTimeScale;
float _counter = 0f;
float _fixedDeltaTime;

_counter += localTimeScale.DeltaTime;
_fixedCounter += localTimeScale.FixedDeltaTime;
```

## Getting & Setting the Value

The "Value" is a `float` representing the percent of "real time". `1f` is essentially 100% of `Time.deltaTime`. The `Value` property will return the current value, and you can also specifically set this value as well using `SetValue(float newValue)`.

{% hint style="warning" %}
If you're using the [`MagicTimeUser`](/magic-pig-games/magic-time-local-time-scale/magic-time-user.md) or [`IHaveLocalTime`](/magic-pig-games/magic-time-local-time-scale/magic-time-user/ihavelocaltime.md) interface, often you'll want to know the value of the combined time scales affecting that object. In that case, use the `TimeScale` property.
{% endhint %}

```csharp
// Get the value
LocalTimeScale localTimeScale;
var currentValue = localTimeScale.Value;

// Set the value
float newValue = 0.5f;
localTimeScale.SetValue(newValue);
```

{% hint style="success" %}
When the value is changed, the UnityEvent `OnTimeScaleChangedUnityEvent` and Event `OnTimeScaleChanged` will be triggered for any subscribers.

If the value is changed to `0f` (with or without using the `Pause()` method), the `OnPaused` and `OnPausedUnityEvent` events will be called.

Similarly, if the value changes from `0f` to something else, even without using the `Resume()` method, the `OnResumed` and `OnResumedUnityEvent` will be called.
{% endhint %}

## Pausing and Resuming

The `Pause()` and `Resume()` methods will set value to `0f`, and then return the value to the last cached value. If you know the resumed value should be the same as what it was prior to the "pause" action, then this is often a simpler way of handling this logic. Otherwise, you can always just `SetValue(0f)` manually.

```csharp
// Pause this specific localTimeScale
localTimeScale.Pause(); // Will cache the current Value before setting it to 0f.

// Resume this specific localTimeScale
localTimeScale.Resume(); // This will reset to the value when Pause() was called.
```

## Subscribing

Any `IHaveLocalTime` object can subscribe to a `LocalTimeScale` object. This will ensure the object gets event notifications from the `LocalTimeScale`.

{% hint style="warning" %}
Remember, the actual calculations for combined time scale will be handled by the `IHaveLocalTime` object.
{% endhint %}

```csharp
// This is from the "SubscribeToLocalTimeScale(LocalTimeScale myTimeScale)" 
// method on MagicTimeUser.cs

// Can't subscribe to the same timeScale twice.
if (SubscribedTimeScales.Contains(myTimeScale)) return;

SubscribedTimeScales.Add(myTimeScale);
myTimeScale.Subscribe(this);
myTimeScale.OnTimeScaleChanged += OnTimeScaleChanged;

// In this example, we keep track of the timeScales we're subscribed to, and subscribe
// to them at the same time.
```

When subscribing, the `OnSubscribed` and `OnSubscribedUnityEvent` will be called.=

### Information About Subscribers

Subscribers are stored in a `HashSet<IHaveLocalTime>` so there is no `index` available. There are a few helpful properties that provide more information about subscribers to a specific Local Time Scale.

```csharp
LocalTimeScale localTimeScale;

// Check the number of subscribers
if (localTimeScale.SubscriberCount == 0)
    return;

// Get the string name of those subscribed
foreach(var subscriberName in localTimeScale.SubscriberNames)
{
    Debug.Log($"{subscriberName} is subscribed");
}

// Get the GameObject of those subscribed
foreach(var subscriberObject in SubscriberGameObjects)
{
    DoSomethingWithSubscriber(subscriberObject);
}
```

## Unsubscribing

You can use the `UnsubscribeAll()` method to call `Unsubscribe()` on all current subscribers.

The `Unsubscribe(IHaveLocalTime subscriber)` method does a few things, if the `subscriber` passed in is actually subscribed.

First, it will remove the `subscriber` from the `Subscribers` list, as you might expect. But it also will call `subscriber.UnsubscribeFromLocalTimeScale(this)`, which allows the subscriber to take any actions as needed.

```csharp
// This is the method from MagicTimeUser.cs
public virtual void UnsubscribeFromLocalTimeScale(LocalTimeScale timeScale)
{
    if (timeScale == null)
        return;

    // If it is in our list, then unsubscribe and remove it.
    if (SubscribedTimeScales.Contains(timeScale))
    {
        timeScale.Unsubscribe(this);
        SubscribedTimeScales.Remove(timeScale);
    }
            
    // This can be called from the LocalTimeScale, so we may need to reset the desired timeScale, 
    // even if the timeScale is not in our list.
    ResetDesiredTimeScale();
}
```

Next, the `OnUnsubscribed` and `OnUnsubscribedUnityEvent` will be called as well, on the Local Time Scale object. Both of these will pass the subscriber (`IHaveLocalTime`) object in as a parameter.

Finally, if `AutoRemoveWhenEmpty` is `true`, the time scale will be removed. See details below.

## Automatically Removing the `LocalTimeScale`

&#x20;In some cases, you may wish to automatically remove a LocalTimeScale when there are no subscribers.

```csharp
localTimeScale.AutoRemoveWhenEmpty = true;
```

Set `AutoRemoveWhenEmpty` to `true`, and then whenever subscribers `Unsubscribe()` from the Local Time Scale, if there are no subscribers left, then the `MagicTimeManager` method `RemoveTimeScale()` method will be called, removing this object.

The check only happens when the `Unsubscribe()` method is called, so you can safely set this value to `true` before any subscribers are active.

## Subscribing to Events

Classes can subscribe to individual events on the `LocalTimeScale` class. This is useful to perform actions based on changes to the Local Time Scale.

In the example below, from `ZoneColorChanger.cs` in the demo, we subscribe and unsubscribe to events on the `LocalTimeScale` attached to a specific time zone.

{% hint style="success" %}
In this case, the `LocalTimeScale` instance is created at runtime, so it will not be availalbe immediately. To handle this, we can subscribe via a Coroutine, which is started `OnEnable()`.
{% endhint %}

```csharp
private void OnEnable() => StartCoroutine(SubscribeToTimeScale());

private void OnDisable()
{
    timeZone.TimeScale.OnSubscribed -= OnSubscribed;
    timeZone.TimeScale.OnUnsubscribed -= OnUnsubscribed;
}

private IEnumerator SubscribeToTimeScale()
{
    yield return new WaitUntil(() => timeZone.TimeScale != null);
    timeZone.TimeScale.OnSubscribed += OnSubscribed;
    timeZone.TimeScale.OnUnsubscribed += OnUnsubscribed;
}

// Handle the events -- make sure the object passed is the right type
private void OnSubscribed(object go)
{
    var newObject = (IHaveLocalTime)go;
    if (newObject == null) return;
            
    var newGameObject = newObject.GameObject;
    if (newGameObject == null) return;
            
    AddColor(newGameObject);
}

private void OnUnsubscribed(object go)
{
    var newObject = (IHaveLocalTime)go;
    if (newObject == null) return;
            
    var newGameObject = newObject.GameObject;
    if (newGameObject == null) return;
            
    RemoveColor(newGameObject);
}
```
