# Magic Time User Scripting

I hope you find it easy to interact with a `MagicTimeUser` object, using the properties and methods provided.

{% hint style="success" %}
Check out the full `MagicTimeUser` class for all the details on the methods and properties available.
{% endhint %}

## Time Control

Most times you would usually use `Time.deltaTime` to handle something related to this object, you will probably want to use the `DeltaTime` property instead. This will return `Time.deltaTime` scaled down by the `magicTimeUser.TimeScale`. There are similar properties for `FixedTime` and `UnscaledDeltaTime`.

{% hint style="info" %}
`Time.unscaledDeltaTime` will return the last frame time without taking `Time.timeScale` into account.
{% endhint %}

### Main Time Properties

Here are some simple exampels of how you might use the main time properties.

```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!
```

## Moving based on `DeltaTime`

In this example, we have a generic Move() method which handles objects that may or may not have a MagicTimeUser component on them, selecting the appropriate `DeltaTime` to use.

```csharp
private void Move()
{
    var deltaTime = MagicTimeUser == null ? Time.deltaTime : MagicTimeUser.DeltaTime;
    transform.Translate(LocalDirection * (speed * deltaTime), Space.Self);
}
```

## Adjusting object locomotion speed with `InverseTimeScale`

We may not always want to scale values by the `TimeScale` value. To achieve a "running in slow motion" effect, where the "Locomotion" animation is determined by the distance a character is moving, we must account for the `TimeScale`.

We use the `InverseTimeScale` to multiply the `metersPerSecond` value. If TimeScale is not exactly `1f`, then `InverseTimeScale` will either increase or decrease the `metersPerSecond` value.

Then, we set the locomotion `float` value on the `Animator` to this animationSpeed.

```csharp
// 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.
//...
```

## Subscribing and Unsubscribing to other `LocalTimeScale` objects

Often you may want to manually subscribe an object to another `LocalTimeScale`. Or perhaps unsubscribe from one.

```csharp
// 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}");
```

## Grabbing and using the `LocalTimeScale` of one object, from another class

Sometimes you may wish to do something with the LocalTimeScale of another object.&#x20;

```csharp
// 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 a `MagicTimeUser`

In cases where you're interacting with `MagicTimeUser` objects, you may have a need to get the `GameObject` associated with that object. The `GameObject` property on `MagicTimeUser` does just that!

Of course, if you create your own class which derives from `MagicTimeUser`, you could add new logic in order to return a different value, if that fits your game.

```csharp
// 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;
    }
}
```


---

# Agent Instructions: 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:

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

The question should be specific, self-contained, and written in natural language.
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.
