> 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 %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://infinitypbr.gitbook.io/magic-pig-games/magic-time-local-time-scale/magic-time-user.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
