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

# 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;
    }
}
```
