figure metadesc_logo_32.png
Activation Graph System for Unity Game Engine.
THIS IS AN ACTIVATION GRAPH SYSTEM, WHICH CONTAINS A NODE EDITOR AND A DIALOG FOR ACTIVATION TRACKING. THE NODE EDITOR WORKS ALSO AS A DEBUGER IN PLAY MODE.
Last changed: January, 2018
Company: metadesc, Helmut Kleber
Author: M. Sc. Dipl. Ing. Helmut Kleber


Table of Contents


List of Figures


1 Introduction

The Activation Graph System contains a node editor for creating your own node based system for e.g. mission, tech and build trees. Originally this asset was a mission graph system, but it is capable to be more than just that. Do not wonder, if the source code comments, the API and this manual contains too much mission entries.
The heart of this activation system is the node logic, that allows you to build a very complex, but also a very simple task sequence in no time. Over this it contains also a visual debuger. The most important node is the task node, which carries for the player relevant data. The another nodes are just for management purposes. The conditions decide how the task or operator node should behave. If a condition fails, the the task triggers its failure outputs, if the conditions are successful, the the success outputs will be triggered. All conditions must be in successful state to trigger the success outputs and just one condition must fail for the failure output.


2 How to use it

There are two prefabs which must be dropped in your scene. The first one is the ActivationGraphManager prefab, which will later contains your graph nodes. The second node is the Demo GUI, which contains the mission dialog and another UI components with mission descriptions. If you don’t want the GUI components, then just remove or disable the MissionGuiManager lines in the ActivationGraphManager.cs file. After this you can call in the “Window” menu the “Activation Graph System”. The graph editor opens. By right click in the node editor window (left window) a context menu opens, where you have the controls for adding and removing nodes and more.
After you added some nodes, you also want to connect them with each other. Hold the left control key down for success connection or alt for failure connection and click on a node with the mouse, then drag and drop the connection to the another node. If you want to remove a connection, then make the same with the control (not alt) key again. If the node is outside the visible screen area, then move the mouse to the side if the window to activate the side scrolling.
Controls are also binded to keyboard keys:
The next steps would be to create your own graph and change or create the UI for your requirements. Then you have to reference some condition nodes in your own code and change or trigger them. This is necessary, because the conditions mostly based on your data.
After you added some nodes, you also want to connect them with each other. Hold the left control (for OSX ’X’) key down for success connection or alt (for OSX ’C’) for failure connection and click on a node with the mouse, then drag and drop the connection to the another node. If you want to remove a connection, then make the same with the control (not alt) key again. If the node is outside the visible screen area at connecting the nodes, then move the mouse to the side if the window to activate the side scrolling. If you don’t have the middle mouse button, then click on left control (for OSX ’X’) and click on the side scrolling area to scroll the view.
You can build up the logical behavior as a graph with lot of possibilities, that satisfy a lot of systems like tech tree, research tree, build tree, crafting system, skill system, mission system and so on. The UI has the task to show the result of the graph and to control it by activating conditions. In the example scene you can see how simple the UI is, because all the logic are in the graph.

3 Basics

Since the version 1.2 more graphs can be exists in the scene. A popup menu can be used to select the graph. The default type for nodes can be set by a popup menu too.
The task node contains the information. Therefore you can set the name, the short name, the long description and more. This is the only one node, which contains information (the descriptions) for the player, the another nodes are just for management purposes. Tasks are condition driven. Normaly each task node contains at least one condition, which decides when and how the task triggers.
figure Task.jpg
Figure 2 Task Node
The task node can be started at playing with the “Activate at Start” attribute. The task itself can be activated multiple times that can be controlled by the “Activation limit” and “Min. activation”. The “Activation limit” limits the activations for the task and the “Min. activation” determines how often the task must be activated for one activation. The task has four actions for the four different internal states. An action for activate, for success, for failure and for disable. The “Type of the node” enumeration can be extended for your type of use. It is important for the UI actualization, to just handle nodes, which are relevant for different purposes. The mission dialog should not show up the tech tree tasks.
figure TaskI.jpg
Figure 3 Task Node Inspector
The Operator node is the most important task management node. It has a lot of functions, which enables a large scale of possibilities. One of the most important feature is to work as an AND node. This node can also have conditions.
figure Op.jpg
Figure 4 Operator Node
The operator node is similar to the task node, but it has no user relevant data (descriptions) and has much more options. Actions and activation restrictions are already described at the task. The “Is And Node” attribute turn this node to a node, which activates its outputs, when all the input connections are activated. You can describe in this way, task A and B must be finished, before C is available. The “Trigger failure” attribute forces a failure output signal. Sometimes a success signal should be inverted. From next three attributes “Success on concurrent tasks”, “Failure on concurrent tasks” and “Inactive on concurrent tasks” just one can be selected. These attributes sets the predecessors to certain state. For example, three quests are available and just one must be done to get the next task. In this case the next task would set the predecessors to success, failure or disable state. An example for success: Rescue A and B or defeat all the enemies. “defeat all the enemies” would automatically include “Rescue A and B”. Example for failure: Rescue A, B or C, but just one can be rescued. If C rescued, then A and B are dead. The disabling concurrent tasks is for: take way A, B or C to the aim. After reaching the aim, the another tasks are nonsense, must be disabled. The operator node can have a weighted probability for outgoing connection. The success and failure outgoing nodes were handled separately. On the picture, the Task4 and Op have 50% chance to be activated, both have the same probability. The “Min out. activation” and “Max out. activation” determine how much outgoing nodes shoud be activated. If “Min out. activation” is 1 and “Max out. activation” is 5, then an integer value will be rolled between these values and that value will determine how much outgoing nodes should be activated. “Restartable” enables the node to be restarted. It sets back the task and the conditions.
figure OperatorI.jpg
Figure 5 Operator Node Inspector
The mission manager inspector window shows up, if you click on the background. The game object name of the mission manager can be changed and a short description can be given. The short description can be used in game or just for documentation purposes. The most important feature in this window is the order of the data tasks. You can click on the button “Add/Refresh ...” to collect all the data tasks to this list. You can remove them or you can sort them in this view. Data tasks, which are not listed in this view, they will be added at starting the game to the end of the list.
figure MI.jpg
Figure 6 Activation Graph Manager Inspector
The success node can be activated by every task or operator node. This can be the end of the game, or just a trigger for a task or an operator node. This node signalizes the positive task completion state.
figure Victory.jpg
Figure 7 Success Node
The “Stop activation system” disables the mission system. This shoud be activated, if the game ends at this node.
figure VictoryI.jpg
Figure 8 Success Node Inspector
The failure node can be activated by every task or operator node. This can be the end of the game, or just a trigger for a task or an operator node. This node signalizes the negative task completion state.
figure Failure.jpg
Figure 9 Failure Node
The “Stop activation system” disables the activation system. This shoud be activated, if the game ends at this node.
figure FailureI.jpg
Figure 10 Failure Node Inspector
A condition node can trigger a task or an operator node. The timer condition acts as a timer, which counts down and triggers at 0. The timer value can be set directly on the node.
figure TimerC.jpg
Figure 11 Timer Condition
The timer node can trigger failure or success signal for a task or operator node. This can be set by the “Trigger failure” attribute. “Time in sec.” is the timer value, which will be counted down to 0. At time 0 the timer node sets its state to success or failure. The “Current time in sec.” visualizes the timer time in play mode for debuging. The timer node can also randomly generate the initial timer value between min and max values.
figure TCI.jpg
Figure 12 Timer Condition Inspector
The user condition has a timer and a counter option. The timer option acts similar to the timer node and the counter option lets the user set a value, which must be counted by the user code. The user code can trigger a success or a failure signal with the operator condition to the task or operator node. This node ment to be controlled by the user.
figure UserC.jpg
Figure 13 User Condition
The attribute “Counter current value” can be increased in your code. This node must be referenced in your code and the counter must be handaled by your code. You can also directly trigger the success or failure state for the condition. Triggering success or failure before the task is active is possible. In this case the task checks the condition in “Check condition timer” time and then immediately receives the signal from the condition. If you don’t want this behavior, then you have to check the state of the conditon. If the condition state is active, then the task has been already activated.
The user conditon can reference items in the container nodes. If the items are available, then the condition switches to the success state. If the task switches to success state, then the consumer conditions make changes to the container. The green led (checkbox) in true mode consumes the item, if this is switched off, then the item will not be consumed. As example, a building 2 needs building 1 as precondition, but building 1 should not be consumed. The “Container Name” can be a reference to a container manager or container.
figure UCI.jpg
Figure 14 User Condition Inspector
The arrival node is one of the simple condition nodes, which can be used without user code triggering. It contains a collider with trigger mode on. The objects, which should arrive, must be set to this condition node.
figure ArrivalC.jpg
Figure 15 Arrival Condition
The “Trigger failure” allows to trigger a failure signal instead of a success signal. This could be used, when the arrival condition is attached to the enemy, which must be destroeyed before it reaches its aim area. It has also a timer, which can also trigger success or failue signal. With “Add Entry” the game objects can be added to the condition, which must arrive in this area. The area is defined by default with a sphere trigger collider. The collider must be set to the right position. The collider can be any collider that derives from Unity Collider class.
figure ACI.jpg
Figure 16 Arrival Condition Inspector
Defeat condition contains a list of game objects, which must be defeated.
figure DefeatC.jpg
Figure 17 Defeat Condition
With the “Add Entry” the game objects can be added to the condition, which must be defeated.
figure DCI.jpg
Figure 18 Defeat Condition Inspector
Survive condition contains a list of game objects, which must survive. The timer always triggers failure. “Defeat at least” defines how much targets must be defeated. It can be more then the defined game objects. in this case you have to add more objects to the list.
figure SurviveC.jpg
Figure 19 Survive Condition
With “Add Entry” the game objects can be added to the condition, which must survive. The timer always triggers success. “Survive at least” defines how much targets must survive. It can be more then the defined game objects. in this case you have to add more objects to the list.
figure SCI.jpg
Figure 20 Survive Condition Inspector
The container node preservs the items, on that the user condition can have dependencies.
figure C.jpg
Figure 21 Container
The container has a lower limit 0 and an upper limit “Container Max Weight Limit”. The “Weight” and “Count” attributes are float number, to allow more precise inputs if necessary. If the upper/lower limit reaches, then the user conditions cannot add more or remove more items from the container. The times have a “Name”, “Count” for counting the items, “Weight” and “MaxW” (max weight). The items can be sorted, but it is not game relevant. Items can be accessed by name, but it is fast, because behind the list a dictionary speeds up getting the container item by name.
figure CI.jpg
Figure 22 Container Inspector
The container manager is a container for container. It can reference one or more container. Sometimes you need more container for different reasons. One reason is the readability of the graph, so instead of one global container more container with different purposes. (e.g. UnitContainer, BuildingContainer) Another reason could be for example, in an RTS game the factory could have a container for resources but an another building, like a silo, could also have a container for the same resource. In this case both container would be used for building a unit or building.
figure CM.jpg
Figure 23 Container Manager
Mainly it contains a list of containers, which are referenced by name. Getting the container items is also speeded up by dictionary. The order of the container is important, because the items will be dropped in the first one and then in the second one, if the first one is full. A method can be called for notify value changes.
figure CMI.jpg
Figure 24 Container Manager Inspector


4 Examples

This is the mission architecture in the example scene, which is included in this asset. Nodes start normally on the left side and ends on the right side. Connections, which are on the right side, are outputs and on the left side are inputs. Conditons and failure nodes can be connected on the top side of the node or on the bottom side. The connections for them are obvious. The activated checkbox in left upper corner signalizes the “start at play” nodes. In this case the “Op” node and the “TaskTimer” nodes start at game play. The “Op” node is delayed with 5 sec. to let the “TaskTimer” task start at first, which then shows up as current mission for 5 seconds. The interesting part is the “TaskTimer” and “Op1” node connection. The “TaskTimer” triggers the failure node, when its timer condition counts to 0. After 46 sec. But if “Op1” will be triggered, then it will trigger the success state on the predecessors. This is a feature on the operator node, the checkbox in right upper corner signalizes this behavior. The “TaskTimer” predecessor switches to the success state and triggers the success output, which are not available. In success state the task does not check anymore its conditions, the “TaskTimer” now remains in success state and is not able to trigger the “Failure” node anymore. In this way, the count down timer has been deactivated. In my strategy game I mostly use a simple mission system with timer, arrival and user conditions, but who knows, probably I will need a complex structure and that is possible with this activation system.
figure Dialog.jpg
Figure 25 Mission Example
The mission graph in running scene.
figure Main1Run.jpg
Figure 26 Mission Example Graph
A building system with the actiavtion graph. More products can be built, which depends on each other. This system can be used also for a skill tree. For a skill tree, the UI would be changed by adding some edges between the clickable buttons. The UI gathers the items automatically in this case.
figure BUI.jpg
Figure 27 Build System Example
Part of the graph for the build system.
figure BuildGraph.png
Figure 28 Build System Example Graph Part
Simple crafting dialog. Items have a description and the number of needed items will be calculated by the consumer conditions. The container widgets shows the content of the container managers container. The UI creates the items automatically.
figure CUI.jpg
Figure 29 Crafting Example
The graph of the simple crafting. Cn’s are consumer conditions and Tn’s are the trigger conditions, which are connected to a button. The data task activate itself to allow building the item again.
figure CG.jpg
Figure 30 Crafting Example Graph


5 Implementation

All the source code is visible for you. The sound files are from angry bot Unity project, which can be downloaded free from the Unity Asset Store. The API is also available.
Source code, base nodes are not described:


6 Outlook

This asset is a part of an upcoming RTS (BlackUtopia, www.metadesc.com). It is already used by this game for building, researching, upgrading and enabling skills for different purposes. The RTS game has a high complexity (about 450 task nodes, where each task node has 2 internal condition nodes), where this node system is evaulated. The version >= 1.4.2 works well under Unity 5.6.3f1.


figure metadesc_logo_32.png