Sequence Instance

So far we have covered the Sequence object and the Effect object, but we’ve left out the third object that you can use to control your movement effects; the SequenceInstance object. In this section we’re going to use SequenceInstance extensively, so here are some basic facts about it:

You can’t create a SequenceInstance object directly, but every time you call Movement.Run one will be created for that particular running instance and returned to you. The SequenceInstance is a very powerful variable since it allows you to modify many of the fields that the effect is using while the effect is running.

There are also a couple of options exposed through the SequenceInstance that are not available to be set in either the Effect or Sequence. These are SequenceInstance.Loop and SequenceInstance.Timescale.

In order to save memory allocations SequenceInstance variables use an object pooling system. This has a lot of advantages when it comes to performance, but it also has one downside: If you hold on to a SequenceInstance variable after the sequence that it points to has finished running, then that SequenceInstance will eventually be recycled and you could end up changing values on a completely random sequence.

There are two ways that you can address this issue:

  1. You can cache the value of SequenceInstance.RecycleCount, and stop using the reference if that value is ever incremented.
  2. Or you can set SequenceInstance.ExcludeFromPooling to true, which will keep that particular SequenceInstance from being recycled. As long as you release your reference at some point the memory manager will come and delete the SequenceInstance eventually.

Changing the Timescale

There are a couple of ways to control the rate of time on your movement effects.

  1. The first way is to change Unity’s Timescale in Edit/Project Settings/Time in the Unity Editor, or in code by changing Time.timeScale. Unity’s timescale is a float that defaults to 1. If you change it to 0.5 then your app will run at 50% speed. If it’s 0 then everything in your game will pause. If you set it to a negative number then your app will not run backwards.. it will just pause and not resume correctly, so avoid setting Unity’s timescale negative.
  2. Sequence.IgnoreUnityTimescale can be set on a sequence before you run it (it defaults to false.) When this is true, the sequence will calculate time independently of Unity’s timescale. This can be very handy for situations where you have a menu that you want to run movement effects on (like the window sliding in). You can set all of the effects that act on your menus to IgnoreUnityTimescale = true, and then you can pause time in the rest of the app by setting Unity’s timescale to 0.
  3. The last way is to change the timescale on a per-effect basis using SequenceInstance.Timescale. SequenceInstance.Timescale in that it’s a float that defaults to 1, 0.5 will run at 50% speed and 0 will pause the sequence. This value, however, can be set negative to run the sequence backwards through time. Unless Sequence.IgnoreUnityTimescale is true, this value will be multiplied with Unity’s Timescale. For example, if both Unity’s timescale and the sequence’s timescale are set to 0.5 then the sequence will be running at 1/4 speed (0.5 * 0.5).

Repeating Sequences

One very useful variable is SequenceInstance.Loop. So long as this boolean is set to true then the sequence will loop over to the first effect after reaching the last effect.

Demo #3 uses this line in order to create looping behavior:

Movement.Run(faceRandom).Loop = true;

 
Movement.Run returns the SequenceInstance. We don’t store the SequenceInstance in this case even though we could, we just change the Loop field to true. If nothing else was going on then this would create a sequence that would never end, but it doesn’t in this case because we’ve set Effect.ContinueIf so it can exit the sequence as soon as a variable is set to true. This is another way to run a sequence, it’s a bit like defining a while loop with while(true) and then putting a break statement in the loop somewhere.

Another way to use SequenceInstance.Loop would be to store the SequenceInstance object in some manager script and then set it to false from your manager script when something changed. This might be useful if, for example, you wanted to put some glittery sparkles around an important object in your scene. Once the user picked up the object you could simply set Loop to false. That way the sparkles would hang around for a little bit after you picked up the item rather than instantly going away.

Changing Key Values on the Fly

The SequenceInstance object has a few fields that can be set in either the Sequence object or the Effect object. These are SequenceInstance.Inertia, SequenceInstance.Elasticity, SequenceInstance.StartValue, and SequenceInstance.EndValue. It also have variables for SequenceInstance.Velocity and SequenceInstance.CurrentValue.

  1. In the Sequence object, Inertia and Elasticity set the initial values for these fields. However, by changing the values for Inertia and Elasticity in the SequenceInstance object you can change these values on the fly. There is a good demonstration of how that is done in Demo #1. In fact, if you were so inclined, you could pass one effect’s SequenceInstance as the reference variable of another effect and run an effect on the Inertia and Elasticity to make their values change over time. This could be used to create really interesting mechanics, like a car whose controls got more and more squishy the longer you tried to drive it.
  2. The Effect object has methods to RetrieveStartValue and RetireveEndValue. The result of those two actions are stored in the SequenceInstance under StartValue and EndValue. You can change the StartValue and EndValue while the sequence is running and the position will be updated as if those were always the StartValue and EndValue. As an example, lets take a simple Effect that runs a float from a StartValue of 1.0 to an EndValue of 2.0. If our effect happens to be 50% done and we change StartValue to -2.0 then the current value will jump from the 1.5 it is currently at to 0.0. Smoothing can smooth out that transition so that it moves over to the new position over several frames, but even with smoothing it’s a good idea to change StartValue or EndValue gradually and not make them jump around too much.
  3. SequenceInstance.CurrentValue is the current value after all smoothing effects. If no smoothing effects are enabled then changing this value won’t accomplish much, since it will just jump back into position instantly. However, if you have something like Elasticity enabled then changing CurrentValue can be somewhat like pulling on a rubber band.. as soon as you release it the effect will bounce back into place. This can be useful since it will have little or no effect on the eventual path of the object, but can give your app a good deal of juiciness.
  4. You won’t see a result from changing SequenceInstance.Velocity unless Elasticity is enabled. If you change it while Elasticity is enabled then you’ll see your object fly off in the direction you specified and then turn around and come back. Once again, as an example, if you had a zipline running along a track and something came by and hit the zipline from the side then you could transfer the intruding object’s velocity into the zipline and it would bounce back and forth on it’s track.