> 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/magic-time-user.md).

# Magic Time User

**Magic Time User** is a `MonoBehaviour` which implements `IUseMagicTime`. Objects which will utilize the **Magic Time** system should inherit from `MagicTimeUser`, so they automatically work.&#x20;

{% hint style="info" %}
You can create your own implementation logic either by creating your own [`IUseMagicTime`](/magic-pig-games/magic-time-local-time-scale/magic-time-user/ihavelocaltime.md) class, or creating a new class which derives from `MagicTimeUser` and overrides the methods you'd like to customize.
{% endhint %}

## "Local" `LocalTimeScale`

Each `MagicTimeUser` object will have its own `LocalTimeScale` automatically. This is unique and specific to this object, and its value will be combined with any other Local Time Scales that this object subscribes to.

## Main Methods and Properties

These are the main methods and properties you'll likely interact with most often.&#x20;

### Time Properties

**`DeltaTime`**, **`FixedDeltaTime`**, and **`UnscaledDeltaTime`** will replace `Time.deltaTime`, `Time.fixedDeltaTime`, and `Time.unscaledDeltaTime` in your code. Anywhere that you would have used `Time.deltaTime`, you should use `DeltaTime` instead.

**`TimeScale`** is the actual scale currently set based on all of the subscribed `LocalTimeScale` objects, compared to normal speed (`Time.timeScale` = `1f`).&#x20;

**`InverseTimeScale`** is the value you would need to multiple `TimeScale` by in order to get `Time.timeScale`. This is useful for multiplying things that you don't want to be slowed down, when they otherwise would. *(See the "animation" example in the* [*Magic Time User Scripting*](/magic-pig-games/magic-time-local-time-scale/magic-time-user/magic-time-user-scripting.md) *page.)*

```csharp
// From a class that is IUseMagicTime or inherits from MagicTimeUser
float speedThisFrame = speed * DeltaTime
float fixedSpeedThisFrame = fixedSpeed * FixedDeltaTime;
float speedThisFrameVersion2 = speed * UnscaledDeltaTime;
Debug.Log($"TimeScale for this object is currently {TimeScale}"); // a float!

// Accounting for TimeScale changes in the Animation speed using InverseTimeScale
//...
var metersPerSecond = distance / deltaTimeToUse;
var animationSpeed = 0f;
if (metersPerSecond > 0 && Owner.TimeScale > 0)
    animationSpeed = metersPerSecond * Owner.InverseTimeScale;
animator.SetFloat(locomotionString, animationSpeed, animatorDampTime, Time.deltaTime);
// The above example ensures the "locomotion" speed remains steady, even as the
// object slows down. This gives it the "running in slow motion" effect.
//...

// Subscribe to a specific LocalTimeScale
LocalTimeScale otherTimeScale;
Debug.Log($"TimeScale before adding {otherTimeScale.name}: {magicTimeUser.TimeScale}");
magicTimeUser.SubscribeToLocalTimeScale(otherTimeScale);
Debug.Log($"TimeScale after adding {otherTimeScale.name}: {magicTimeUser.TimeScale}");

// Unsubscribing from a specific LocalTimeScale
LocalTimeScale otherTimeScale;
Debug.Log($"TimeScale before removing {otherTimeScale.name}: {magicTimeUser.TimeScale}");
magicTimeUser.UnsubscribeFromLocalTimeScale(otherTimeScale);
Debug.Log($"TimeScale after removing {otherTimeScale.name}: {magicTimeUser.TimeScale}");

// Interacting with the LocalTimeScale on the object from another class
if (otherObject is IUseMagicTime magicTimeUser)
{
    LocalTimeScale otherTimeScale = magicTimeUser.LocalTimeScale;
    float otherObjectsTimeScale = otherTimeScale.LocalTimeScaleValue;
}

// Getting the gameObject from IUseMagicTime
protected virtual void OnCollisionEnter(Collider other)
{
    if (other.isTrigger) return;
            
    var magicTimeUser = other.GetComponentInParent<IUseMagicTime>();
    if (magicTimeUser != null)
    {
        GameObject otherObject = magicTimeUser.GameObject;
    }
}
```

Check the [Magic Time User Scripting](/magic-pig-games/magic-time-local-time-scale/magic-time-user/magic-time-user-scripting.md) page for more scripting documentation.&#x20;

## Inspector Options

Once added to your class, some fields will be exposed in the Inspector.

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

## Initial Time Scales

These are `LocalTimeScale` Scriptable Objects which you want to subscribe to at runtime. These will connect to the instances of those objects via the [Magic Time Manager](/magic-pig-games/magic-time-local-time-scale/magic-time-manager.md) in your scene.

## Transition Settings

Whenever the combined `TimeScale` value changes, the value of `TimeScale` will transition to the new value.

### Transition Duration

This is how long the transition lasts. Set this value to `0f` to skip transitioning altogether.

### Transition Curve

This is the curve used for the transition, if you'd like to customize the experience.

### Default Time Scale

This is the default time scale value for this objects `LocalTimeScale` object.

## Customization Example

Often you may want your object to subscribe to some `LocalTimeScales`, but not others, depending on the type of object it is in your game. In my own project, I have "Enemy" and "Player" Local Time Scales, and characters of those types will subscribe to one or the other.

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

Here I have exposed two additional lists, one for the "Player" and one for the "Enemy". In my code, I ensure the character only subscribes to the correct list of `LocalTimeScales`.

<pre class="language-csharp"><code class="lang-csharp"><strong>// Note that this overrides the coroutine on MagicTimeUser!
</strong><strong>public override IEnumerator SubscribeToInitialTimeScales()
</strong>{
    // Wait for the base class coroutine to finish [Don't forget this step!]
    yield return base.SubscribeToInitialTimeScales();
    
    // Subscribe to the additional time scales based on the IsPlayer value
    foreach (var timeScale in IsPlayer ? playerTimeScales : enemyTimeScales)
    {
        var localTimeScale = MagicTimeManager.Instance.TimeScale(timeScale.name);
        SubscribeToLocalTimeScale(localTimeScale);
    }
}
</code></pre>

{% content-ref url="/pages/vePIDkKmy1lfk4ZwF9Kj" %}
[Magic Time User Scripting](/magic-pig-games/magic-time-local-time-scale/magic-time-user/magic-time-user-scripting.md)
{% endcontent-ref %}

{% content-ref url="/pages/hC2HMeePUoLcnHkbTiG6" %}
[IHaveLocalTime](/magic-pig-games/magic-time-local-time-scale/magic-time-user/ihavelocaltime.md)
{% endcontent-ref %}
