NEWS COMMUNITY STORE TUTORIALS ROKOJORI ACTION LIBRARY ROKOJORI ACTION LIBRARY TUTORIALS SIGN UP LOGIN LOGOUT ROKOJORI NEWSLETTER SIGN UP LOGIN LOGOUT NEWS COMMUNITY STORE TUTORIALS ROKOJORI ACTION LIBRARY ROKOJORI ACTION LIBRARY TUTORIALS TOGGLE FULLSCREEN VOLLBILD AN/AUS image/svg+xml image/svg+xml image/svg+xml ASYNCHRONOUS SEQUENCE ACTIONS
Sequences Over Multiple Frames/Time Spans
image/svg+xml image/svg+xml Sequences Over Multiple Frames/Time Spans image/svg+xml






ACTIONS WITH A START AND END

While Actions are convenient to execute things immediately, there are occasions, where you need to wait for something until you can continue.

This can be waiting for things to load or animations that need to end or simple waiting for an user input.

Whenever a simple animation is too rigid, SequenceActions become very handy. In fact, most of the time, they are way more flexible than animation clips, because their setup is so simple.

In a nutshell: SequenceActions extend Actions, so that they have a start and an end. They are programmed so that they can do things over multiple frames - like tweens or loading scenes and resources.

Although this might be already useful, it's actually not that relevant in an ActionList.

Since an ActionList executes every child Action immediately, they still start at the same time and only their end points differ:




HELLO ACTION SEQUENCE!

Isn't the name excellent, SequenceActions and ActionSequence!
So what does an ActionSequence?

An ActionSequence executes all child Actions and child SequenceActions in sequence and only executes the next Action when the previous Action was finished.

In programming terms it's similar to async programming, where code awaits the following commands.

The advantage over animations is that the timing does not to be fixed, but can depend on different factors than time.

But... Is it enough?




DO IT IN PARALLEL!

So what if want to start Actions immediately, but you want to wait until all are finished? The normal ActionList does not define a different end, in fact it would, when placed in an ActionSequence, end immediately.

In this case you need a Parallel. It comes with two modes: First_Finishes_Sequence and Wait_For_All_To_Finish.

With this two modes, you can either continue a sequence after the first that ended the execution or wait until all other SequenceActions are ready.

By the way, it has also a toggle to ignore normal Actions, when using First_Finishes_Sequence.




WRITING A CUSTOM SEQUENCE ACTION

SequenceActions are a bit more complex to write than Actions. They still happen in the one function: _OnTrigger()
But they have two new methods that need to be called to make them work.

To start a SequenceAction use this and store the id: var id = DispatchStart()
And to end it, pass the returned id to this method: DispatchEnd( id )

It's the same for GDScript, just extend RJ_SequenceAction and than implement the method: _onTrigger( action:GDScriptSequenceAction )
Also use the methods, but use the passed SequenceAction to call them.

To start a SequenceAction call the method and store the id: var id = sequenceAction.DispatchStart()
And to end it, pass the returned id: sequenceAction.DispatchEnd( id )


C#: using Godot; using Rokojori; [Tool, GlobalClass] public partial class MyAction:SequenceAction { protected override void _OnTrigger() { GD.Print( "Wait a second..." ); var id = DispatchStart(); WorkAndFinish( id ); } async Task WorkAndFinish( int id ) { var timer = GetTree().CreateTimer( 1.0 ); await ToSignal( timer, SceneTreeTimer.SignalName.Timeout ); DispatchEnd( id ); GD.Print( "Hello World!" ); } }

GDScript: ## -- ## -- @tool class_name MySequenceAction extends RJ_SequenceAction func _onTrigger( sequenceAction:GDScriptSequenceAction ) -> void: print( "Wait a second..." ); var id = sequenceAction.DispatchStart(); workAndFinish( sequenceAction, id ); ## --- func workAndFinish( sequenceAction:GDScriptSequenceAction, id:int ) var timer = get_tree().create_timer( 1.0 ); await timer.timeout; sequenceAction.DispatchEnd( id ); print( "Hello World!" ); ## ---




WHY DO YOU NEED THE ID?

While Actions start immediately and never have the problem to identify which ones are finished, SequenceActions have to know which sequences started and more importantly which ended.

The strength of SequenceActions is that they can start multiple ones in parallel, if needed. But this also means this needs to be implemented to support it.

If you don't want to support a parallel processing, than before you call DispatchStart check if another one is running already and exit early (you need to cache whether it is running).

The ActionSequence has already a flag No Overlays you can toggle if you don't want to allow multiple sequences in parallel.

Keep this in mind, when you want to support parallel processing of the SequenceAction.

This usually means, that when you cache something you have to use a closure to capture all variables for each context of this one execution of the SequenceAction.

Alternatively, you can store the properties of running SequenceAction calls in dictionaries, mapping the id of the SequenceAction to a property.

Built-in SequenceActions always support multiple processing.










TO ROKOJORI ACTION LIBRARY TUTORIALS







All social media brands are registrated trademarks and belong to their respective owners.





CONTACT IMPRINT TERMS OF USE PRIVACY © ROKOROJI ® 2021 rokojori.com
CONTACT IMPRINT TERMS OF USE PRIVACY © ROKOROJI ® 2021 rokojori.com
We are using cookies on this site. Read more... Wir benutzen Cookies auf dieser Seite. Mehr lesen...