Magic Time User Scripting
v1.0
I hope you find it easy to interact with a MagicTimeUser
object, using the properties and methods provided.
Check out the full MagicTimeUser
class for all the details on the methods and properties available.
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
.
Main Time Properties
Here are some simple exampels of how you might use the main time properties.
// 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
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.
private void Move()
{
var deltaTime = MagicTimeUser == null ? Time.deltaTime : MagicTimeUser.DeltaTime;
transform.Translate(LocalDirection * (speed * deltaTime), Space.Self);
}
Adjusting object locomotion speed with InverseTimeScale
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.
// 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
LocalTimeScale
objectsOften you may want to manually subscribe an object to another LocalTimeScale
. Or perhaps unsubscribe from one.
// 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
LocalTimeScale
of one object, from another classSometimes you may wish to do something with the LocalTimeScale of another object.
// 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
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.
// 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;
}
}
Last updated
Was this helpful?