Mono Node
An extension of the Node Framework that seamlessly integrates with Unity's GameObject hierarchy system.
Overview
MonoNode allows any MonoBehaviour to become a node in your hierarchy by inheriting from MonoNode<T>
. It maintains synchronization between the GameObject hierarchy and the node structure.
Key Features
Automatic GameObject hierarchy synchronization
Inspector-based node structure management
Safe node registration system
Flexible parent-child relationship handling
Container nodes for structural organization
Why Use It
Mono Node Framework bridges Unity's Component system with our powerful Node Framework. It transforms individual Components into nodes while respecting Unity's hierarchical structure.
Key Features:
Component Integration: Turn any MonoBehaviour into a powerful node
Hierarchy Respect: Maintains Unity's natural GameObject relationships
Extended Functionality: Access both Node Framework features and Mono-specific extensions
Natural Workflow: Feels native to Unity while providing node capabilities
Performance Optimized: Designed for efficient operation within Unity's component system
Perfect for developers who want node-based architecture while leveraging Unity's component system to its fullest.
Creating a MonoNode
// Define your MonoNode component
public class MyGameNode : MonoNode<MyGameNode>
{
protected override void Awake()
{
base.Awake(); // => NodeAwake by Root Node only
// normal Awake process
}
protected override void NodeAwake()
{
base.NodeAwake();
// Called when node structure is ready
// Put your initial codes here that required the node structure
// NodeReady will be true after invoked
}
}
NodeAwake() will called by Root Node only. Process will be ignored in all ChildNodes.
Inspector Controls

Node ID
Optional unique identifier for the node
Leave empty if the node type is unique in your scene or will never be lookup
Set an ID when you have multiple nodes of the same type
Used for specific node lookup and reference
Auto Registry
Controls automatic node registration during Awake
When
true
: Node automatically registers to the node systemWhen
false
: Manual registration required
MonoNode Structure
Building MonoNode<T>
structure is not required any manual process.
When a GameObject
nested with MonoNode<T>
components without gap, the whole structure will be built on Awake() automatically.
Auto Register for MonoNode
According to construction of GameObject and Component in Unity, the handle of Auto Register of Node is different from pure Node.
Basic rules are:
GameObject
exists in Hierarchy -Auto Registry
is recommended unless you want to handle yourself.GameObject
will be Instantiated by code (pool object) -Auto Registry
should be off because related node data is not ready.Other case - It's not neccessary to get the nodes thought Node<T>.Get(), you can turn off
Auto Registry
.
Manual Register
// for instantiating object by code, such as pool item.
public class YourComponent : MonoNode<YourComponent>, IPoolItem
{
public void OnTakeFromPool()
{
// Register this Node
this.Register();
}
public void OnReturnToPool()
{
// Unregister this Node
this.Unregister();
}
}
Best practices for managing MonoNodes manually, please remember to Register and Unregister, unless the node is not necessary to exposed for other object.
Accessing Nodes
// Get parent of specific type
MyGameNode parent = node.MonoParent<MyGameNode>();
// Get child of specific type
MyGameNode firstChild = node.MonoChild<MyGameNode>();
MyGameNode namedChild = node.MonoChild<MyGameNode>("specificId");
// Get all children of specific type
IEnumerable<MyGameNode> children = node.MonoChildren<MyGameNode>();
IEnumerable<MyGameNode> allLevelChildren = node.MonoChildrenInAllLevel<MyGameNode>();
// Single instance - ID can be empty
public class PlayerNode : MonoNode<PlayerNode> { }
PlayerNode player = PlayerNode.Get(); // Works fine with single instance
PlayerNode.GetAsync() // Get the PlayerNode that may not ready now
.Then(node => player = node)
.Catch(Debug.LogError);
// Multiple instances - requires ID
public class EnemyNode : MonoNode<EnemyNode> { }
nodeId = "Boss"
EnemyNode boss = EnemyNode.Get("Boss"); // Get specific enemy
EnemyNode.GetAsync("Boss") // Get the EnemyNode that may not ready now
.Then(node => boss = node)
.Catch(Debug.LogError);
Managing Relationships
// Set parent
node.SetParent(parentNode);
// Set as root
node.SetAsRoot();
// Add child
node.AddChild(childNode);
node.AddChildren(childNode1, childNode2);
// Remove relationships
node.RemoveChild(childNode);
node.RemoveChildren();
GameObject parent will also change on node structure change.
SetAsRoot will make GameObject move to root of hierarchy.
Container Nodes
Use ContainerNode
to maintain node hierarchy when dealing with non-functional GameObjects.
More Node Initial States
In some case, action need to rely on other node that is already completed NodeAwake process.
public class YourNode : MonoNode<YourNode>
{
protected override void NodeAwake()
{
base.NodeAwake();
// run stuff after target node is awaken
this.MonoChild<OtherNode>();
.OnNodeReadyAction(() => Debug.Log("childNode is awaken"));
// run with the node parameter
this.MonoChild<OtherNode>();
.OnNodeReadyAction(node => Debug.Log($"childNode {node.Id} is awaken"));
}
}
Important Notes
Node registration occurs during Awake (if autoRegisterToNodeTree is true)
Node structure built during Awake
Custom initialization code should be placed in
NodeAwake()
Best Practices
Always override
StartAfterNodeBuilt()
for initialization that requires node structureLeave ID empty for singleton-like nodes
Use meaningful IDs for multiple instances (e.g., "BossEnemy", "MiniBoss")
Consistent ID naming helps with node retrieval
Consider using enums or constants for frequently used IDs
Regularly update node structure when modifying GameObject hierarchy
Consider disabling autoRegisterToNodeTree if manual control is needed
Last updated