Parallel Action¶
The ParallelAction is used to instantiate two or more Actions simultaneously. Then the user can decide which one to complete first.
Additionally, ParallelAction can modify the Scenegraph tree according to the user’s decisions. ParallelActions are usually linked with critical errors. For example, we may implement a ParallelAction which has a correct and a wrong Action to Perform. If the user decides to complete the correct Action, then the simulation will continue as usual. However, if the user completes the wrong Action (for instance inserting an object in a wrong place) then this behavior will trigger the alternative path and the scenegraph will be modified runtime by adding or removing specific Actions.
For instance, if the user causes damage to a human bone, the scenegraph will populate a new stage that forces the user to correct their mistake by repairing the fracture. In another example, if the user paints a car with the wrong color, scenegraph can add new Actions in order to repaint it.
You can read here a detailed article on ParallelActions.
In this example, we will implement a ParallelAction where the user needs to decide whether to assemble the Knossos model or the Sponza model.
This Action is part of the SampleApp level named AssembleKnossosORSponzaAction
Note
The “normal” path involves the assembly of Knossos and the “alternative” path the assembly of Sponza.
As a result, if the user decides to assemble the Knossos, the scenegraph will move to the next Action. However, if they assemble the Sponza, the alternative path will trigger to add a new Lesson node to the scenegraph runtime.
Blueprint Walk-through¶
Initially, the two actions which will determine the path are created and configured. They are both InsertActions, and are stored as temporary variables for use later on when the ParallelAction is set-up.
The next step is to set a different event listener for each action. The first action will listen to the (automatically assigned) default event, so the remaining actions will need to listen to different events. In this case we only have one alternative action, so we will have it listen to “SponzaPart”.
The final step is to configure the number of the alternative path that each action will trigger upon completion. In our example, the Assemble Knossos
action will trigger the default path (making no change to the scene graph) which is -1
. If the user chooses to assemble Sponza, it will trigger the alternative path 0
SceneGraph Configuration¶
Now we will generate the Lesson node that will be added to the scenegraph in case the user triggers the alternative path.
Note
The next version of MAGES for Unreal (1.0) will include a visual scene-graph editor, but we can still configure the scene-graph manually.
Create a new file named AlternativeLessons.xml
and fill it with the following contents:
<?xml version="1.0"?>
<ArrayOfLessons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lessons>
<Lesson_Name>Sponza Restoration</Lesson_Name>
<Stages>
<Stage_Name>Sponza Stage</Stage_Name>
</Stages>
</Lessons>
</ArrayOfLessons>
In order to convert this lesson node into an alternative one, we will need to tell the scene-graph which action would trigger this node.
<?xml version="1.0"?>
<ArrayOfLessons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lessons>
<Lesson_Name>Sponza Restoration ADD(0|1|0-0|0|0)</Lesson_Name>
<Stages>
<Stage_Name>Sponza Stage</Stage_Name>
</Stages>
</Lessons>
</ArrayOfLessons>
The syntax used here can be described as follows:
<Alternative Type> (
<Trigger Action ID> -
<Additional Node> )
Alternative Type: The type of this alternative path (ADD, DEL, RPL). In this case, it is set to
ADD
since we want this lesson to be added to the scene-graph.Trigger Action ID: The action that can trigger the alternative path. In our case, the action
AssembleKnossosORSponzaAction
will have an LSA ID of010
(Lesson 0, Stage 1, Action 0).Additional Node: In case of an
ADD
AlternativeType this variable sets the left sibling of our added node. In this example, if we set the AdditionalNode to000
, our new node will be added as a sibling next to000
meaning that it will be the100
node (the second Lesson)
We add the Stage and Action nodes to the alternative lesson in the usual way
In our example, if the user inserts the Sponza instead of the Knossos, then this lesson node will be added as the second lesson of the operation. This node contains additional Actions for the Sponza (UseAction and ToolAction) and finally the OperationEnd Action.
In our example, if the user inserts the Sponza instead of the Knossos, then this lesson node will be added as the second lesson of the operation. This node contains additional Actions for the Sponza (UseAction and ToolAction) and finally the OperationEnd Action.
Below you can see the final alternative lesson scenegraph.
<?xml version="1.0"?>
<ArrayOfLessons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lessons>
<Lesson_Name>Sponza Restoration ADD(0|1|0-0|0|0)</Lesson_Name>
<Stages>
<Stage_Name>Sponza Stage</Stage_Name>
<Actions>
<Action>Clean Sponza</Action>
<ActionClassName>UseAction</ActionClassName>
<ActionType>Simple</ActionType>
<AverageActionTime>10.0</AverageActionTime>
<IsDemoApplicable>y</IsDemoApplicable>
</Actions>
<Actions>
<Action>Burn Sponza</Action>
<ActionClassName>UseWithToolActionBP</ActionClassName>
<ActionType>Simple</ActionType>
<AverageActionTime>10.0</AverageActionTime>
<IsDemoApplicable>y</IsDemoApplicable>
</Actions>
<Actions>
<Action>Operation End (Alternative)</Action>
<ActionClassName>OperationEndAlternative</ActionClassName>
<ActionType>Simple</ActionType>
<AverageActionTime>10.0</AverageActionTime>
<IsDemoApplicable>y</IsDemoApplicable>
</Actions>
</Stages>
</Lessons>
</ArrayOfLessons>
The final step is to register the AlternativeLessons.xml
file to our training module. From Unreal, open the SceneGraphPathDefinitions
asset of the operation:
Parallel Action Explanation¶
Now lets see what happens when we start the application.
The scenegraph loads the LSA graph at the Scene Graph
actor on the hierarchy. Additionally, our alternative lesson will be added under a separate actor, the AlternativePathBucket
.
Here is where all the alternative nodes are saved, waiting to be spawned in the scenegraph.
You can see here that the “Sponza Restoration” lesson has the ADD-0 opcode next to the lesson name, signifying that it will be added next to the first lesson.
Now lets move to the AssembleKnossosORSponzaAction
Action that will trigger the alternative path.
As you can see both Actions are Initialized simultaneously, the user should decide which one will complete.
To trigger the alternative path we have to insert the Sponza model.
Upon performing the action by choosing to assemble Sponza, the alternative lesson we created will be inserted into the graph.
Note
Unreal does not record the sibling indices of actor attachments; we use our internal method to keep track of this
As a result, the next actions that the user will execute, will be the alternative actions we specified in the AlternativeLessons.xml file.
Note
Both alternative Actions will Perform()
when completing the ParallelAction.
If you Undo()
and come back to the ParallelAction, the alternative lesson will be deleted from the scenegraph hierarchy (reset).