{"id":1530,"date":"2025-05-08T12:10:17","date_gmt":"2025-05-08T12:10:17","guid":{"rendered":"https:\/\/www.portalsunited.com:443\/?post_type=docs&#038;p=1530"},"modified":"2025-06-10T14:20:30","modified_gmt":"2025-06-10T14:20:30","password":"","slug":"custom-nodes-tutorial-guide","status":"publish","type":"docs","link":"https:\/\/www.portalsunited.com:443\/docs\/custom-nodes-tutorial-guide\/","title":{"rendered":"World Builder &#8211; Custom Nodes Tutorial Guide"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\" id=\"custom-nodes-tutorial-guide\">1. MyDebugNode Tutorial<\/h1>\n\n\n\n<p>The Debug Node lets you print messages to the Unity console \u2013 perfect for tracking values and debugging your node graphs during runtime!<\/p>\n\n\n\n<p>You can find all of our currently implemented Nodes <a href=\"https:\/\/www.portalsunited.com:443\/wp-content\/uploads\/2025\/06\/Node-Scripts.zip\">here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This node takes a string input and logs it to the Unity console, making it easy to debug values and track execution flow in your node-based applications.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-node-script\">1. Create the Node Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes;\n<span class=\"hljs-keyword\">using<\/span> Worldbuilder.Nodes.FileIO;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes.IO;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyNodes<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyDebugNode<\/span> : <span class=\"hljs-title\">NodeBase<\/span>\n    {\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_GUID =&gt; <span class=\"hljs-string\">\"b4fc3090-faf0-4417-88b9-92c04a986117\"<\/span>;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_CLASS_NAME =&gt; <span class=\"hljs-string\">\"MyDebugNode\"<\/span>;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Guid NodeClassGuid =&gt; Guid.Parse(NODE_GUID);\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> NodeClassName =&gt; NODE_CLASS_NAME;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; InputTypes =&gt; m_InputTypes;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; OutputTypes =&gt; m_OutputTypes;\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_InputTypes =\n            <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { NodeFactory.VarType.Flow, NodeFactory.VarType.String };\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_OutputTypes =\n            <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { NodeFactory.VarType.Flow };\n\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_StringInput;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyDebugNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, Guid nodeInstanceGuid<\/span>) :\n            <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeInstanceGuid, <span class=\"hljs-literal\">null<\/span>, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyDebugNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, NodeFile nodeFile, NodeFileEntry nodeFileEntry<\/span>) \n            : <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeFileEntry.Identity, nodeFileEntry, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MakeIO<\/span>(<span class=\"hljs-params\">NodeFileEntry nodeFileEntry<\/span>)\n        <\/span>{\n            Inputs&#91;<span class=\"hljs-number\">0<\/span>].RunAction = RunAction;\n            m_StringInput = Inputs&#91;<span class=\"hljs-number\">1<\/span>];\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">RunAction<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-keyword\">string<\/span> text = m_StringInput.GetString();\n            Debug.Log(<span class=\"hljs-string\">\"MyDebugNode: \"<\/span> + text);\n\n            Run();\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-it-works\">How It Works<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"node-properties-\">Node Properties:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Flow Input<\/strong>: Triggers the node execution<\/li>\n\n\n\n<li><strong>String Input<\/strong>: The message to be logged to the console<\/li>\n\n\n\n<li><strong>Flow Output<\/strong>: Continues execution to the next node<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"implementation-details-\">Implementation Details:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uses Unity&#8217;s <code>Debug.Log()<\/code> method to output messages to the console<\/li>\n\n\n\n<li>Prefixes messages with &#8220;MyDebugNode:&#8221; for easy identification<\/li>\n\n\n\n<li>Calls <code>Run()<\/code> to continue execution to the next node in the sequence<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"runtime-behavior-\">Runtime Behavior:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When the flow input is triggered, the node gets the current string value<\/li>\n\n\n\n<li>Logs the string to the Unity console<\/li>\n\n\n\n<li>Continues execution flow to any connected node<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"using-the-node\">Using the Node<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the MyDebugNode to your node graph<\/li>\n\n\n\n<li>Connect the flow execution from a previous node to its input<\/li>\n\n\n\n<li>Connect a string value to the string input, or manually enter text<\/li>\n\n\n\n<li>Connect the flow output to any subsequent nodes<\/li>\n\n\n\n<li>When executed, the node will print your string to the console and continue execution<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2-mylerpfloat-tutorial\">2. MyLerpFloat Tutorial<\/h2>\n\n\n\n<p>The Lerp Float Node performs linear interpolation between two values \u2013 perfect for creating smooth transitions and animations in your node-based applications!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This node takes two float values (x and y) and a t parameter (0-1), then performs linear interpolation to calculate a value between them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-node-script\">1. Create the Node Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes.IO;\n<span class=\"hljs-keyword\">using<\/span> UnityEngine;\n<span class=\"hljs-keyword\">using<\/span> Worldbuilder.Nodes.FileIO;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">WorldBuilder<\/span>.<span class=\"hljs-title\">Nodes<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyLerpFloat<\/span> : <span class=\"hljs-title\">NodeBase<\/span>, <span class=\"hljs-title\">INodeBase<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_GUID =&gt; <span class=\"hljs-string\">\"69eaba67-8d94-476b-9ec1-9f2b6643b650\"<\/span>;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_CLASS_NAME =&gt; <span class=\"hljs-string\">\"My Lerp (x,y,t)\"<\/span>;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Guid NodeClassGuid =&gt; Guid.Parse(NODE_GUID);\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> NodeClassName =&gt; NODE_CLASS_NAME;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; InputTypes =&gt; m_InputTypes;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; OutputTypes =&gt; m_OutputTypes;\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_InputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { \n            NodeFactory.VarType.Float, \n            NodeFactory.VarType.Float, \n            NodeFactory.VarType.Float \n        };\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_OutputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { \n            NodeFactory.VarType.Float \n        };\n\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_ValueA;\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_ValueB;\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_Scalar;\n\n        <span class=\"hljs-keyword\">private<\/span> FloatOutput m_ResultOutput;\n\n        <span class=\"hljs-keyword\">public<\/span> MyLerpFloat(NodeTree nodeTree, Guid nodeInstanceGuid) :\n            base(nodeTree, nodeInstanceGuid, <span class=\"hljs-literal\">null<\/span>, m_InputTypes, m_OutputTypes)\n        {\n        }\n\n        <span class=\"hljs-keyword\">public<\/span> MyLerpFloat(NodeTree nodeTree, NodeFile nodeFile, NodeFileEntry nodeFileEntry) :\n            base(nodeTree, nodeFileEntry.Identity, nodeFileEntry, m_InputTypes, m_OutputTypes)\n        {\n        }\n\n        <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> MakeIO(NodeFileEntry nodeFileEntry)\n        {\n            m_ValueA = Inputs&#91;<span class=\"hljs-number\">0<\/span>];\n            m_ValueA.DisplayName = <span class=\"hljs-string\">\"x\"<\/span>;\n\n            m_ValueB = Inputs&#91;<span class=\"hljs-number\">1<\/span>];\n            m_ValueB.DisplayName = <span class=\"hljs-string\">\"y\"<\/span>;\n\n            m_Scalar = Inputs&#91;<span class=\"hljs-number\">2<\/span>];\n            m_Scalar.DisplayName = <span class=\"hljs-string\">\"t\"<\/span>;\n\n            m_ResultOutput = Outputs&#91;<span class=\"hljs-number\">0<\/span>] as FloatOutput;\n            m_ResultOutput.DisplayName = <span class=\"hljs-string\">\"result\"<\/span>;\n            m_ResultOutput.SetGetValueFunc(Calc);\n        }\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">float<\/span> Calc()\n        {\n            <span class=\"hljs-keyword\">float<\/span> scalar = Math.Clamp(m_Scalar.GetFloat(), <span class=\"hljs-number\">0.0<\/span>f, <span class=\"hljs-number\">1.0<\/span>f);\n\n            <span class=\"hljs-keyword\">float<\/span> a = m_ValueA.GetFloat();\n            <span class=\"hljs-keyword\">float<\/span> b = m_ValueB.GetFloat();\n            <span class=\"hljs-keyword\">return<\/span> Mathf.Lerp(a, b, scalar);\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-it-works\">How It Works<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"node-properties-\">Node Properties:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>x Input<\/strong>: The starting value<\/li>\n\n\n\n<li><strong>y Input<\/strong>: The ending value<\/li>\n\n\n\n<li><strong>t Input<\/strong>: The interpolation parameter (0-1)<\/li>\n\n\n\n<li><strong>result Output<\/strong>: The interpolated value<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"the-math-behind-it-\">The Math Behind It:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Linear interpolation calculates a point between two values<\/li>\n\n\n\n<li>When t=0, the result equals x<\/li>\n\n\n\n<li>When t=1, the result equals y<\/li>\n\n\n\n<li>When t is between 0 and 1, the result is proportionally between x and y<\/li>\n\n\n\n<li>The formula is: result = x + (y &#8211; x) * t<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"implementation-details-\">Implementation Details:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uses Unity&#8217;s <code>Mathf.Lerp()<\/code> function for the actual calculation<\/li>\n\n\n\n<li>Clamps the t parameter between 0 and 1 to ensure valid results<\/li>\n\n\n\n<li>Returns the interpolated value through the output<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"using-the-node\">Using the Node<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the MyLerpFloat node to your graph<\/li>\n\n\n\n<li>Connect float values to the x and y inputs<\/li>\n\n\n\n<li>Connect a value between 0-1 to the t input<\/li>\n\n\n\n<li>Use the result output anywhere you need the interpolated value<\/li>\n\n\n\n<li>For animation, try connecting a time-based value to t<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3-myroundtofloat-tutorial\">3. MyRoundToFloat Tutorial<\/h2>\n\n\n\n<p>The Round To Float Node rounds decimal values to a specified precision \u2013 perfect for cleaning up calculations and displaying user-friendly numbers!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This node takes a float value and rounds it to a specified number of decimal places, making it ideal for formatting numbers for display or ensuring consistent precision.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-node-script\">1. Create the Node Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> Worldbuilder.Nodes.FileIO;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes.IO;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">WorldBuilder.Nodes<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyRoundToFloatNode<\/span> : <span class=\"hljs-title\">NodeBase<\/span>\n    {\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_GUID =&gt; <span class=\"hljs-string\">\"04a383f8-03df-46d4-b336-dfd4ed1685c6\"<\/span>;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_CLASS_NAME =&gt; <span class=\"hljs-string\">\"My Round To Float\"<\/span>;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Guid NodeClassGuid =&gt; Guid.Parse(NODE_GUID);\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> NodeClassName =&gt; NODE_CLASS_NAME;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; InputTypes =&gt; m_InputTypes;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; OutputTypes =&gt; m_OutputTypes;\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_InputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { \n            NodeFactory.VarType.Float, \n            NodeFactory.VarType.Int \n        };\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_OutputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; { \n            NodeFactory.VarType.Float \n        };\n\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_ValueInput;\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_NrOfDecimalsInput;\n        <span class=\"hljs-keyword\">private<\/span> FloatOutput m_ResultOutput;\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyRoundToFloatNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, Guid nodeInstanceGuid<\/span>) :\n            <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeInstanceGuid, <span class=\"hljs-literal\">null<\/span>, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyRoundToFloatNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, NodeFile nodeFile, NodeFileEntry nodeFileEntry<\/span>) :\n            <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeFileEntry.Identity, nodeFileEntry, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MakeIO<\/span>(<span class=\"hljs-params\">NodeFileEntry nodeFileEntry<\/span>)\n        <\/span>{\n            m_ValueInput = Inputs&#91;<span class=\"hljs-number\">0<\/span>];\n            m_ValueInput.DisplayName = <span class=\"hljs-string\">\"Value\"<\/span>;\n\n            m_NrOfDecimalsInput = Inputs&#91;<span class=\"hljs-number\">1<\/span>];\n            m_NrOfDecimalsInput.DisplayName = <span class=\"hljs-string\">\"Decimal places\"<\/span>;\n\n            m_ResultOutput = Outputs&#91;<span class=\"hljs-number\">0<\/span>] <span class=\"hljs-keyword\">as<\/span> FloatOutput;\n            m_ResultOutput.DisplayName = <span class=\"hljs-string\">\"Rounded Value\"<\/span>;\n            m_ResultOutput.SetGetValueFunc(() =&gt; RoundWithDecimalPlaces(m_NrOfDecimalsInput.GetInt()));\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">float<\/span> <span class=\"hljs-title\">RoundWithDecimalPlaces<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">int<\/span> nrOfDecimalPlaces<\/span>) <\/span>=&gt; \n            (<span class=\"hljs-keyword\">float<\/span>)Math.Round(m_ValueInput.GetFloat(), nrOfDecimalPlaces);\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-it-works\">How It Works<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"node-properties-\">Node Properties:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Value Input<\/strong>: The float value to be rounded<\/li>\n\n\n\n<li><strong>Decimal places Input<\/strong>: Integer specifying how many decimal places to keep<\/li>\n\n\n\n<li><strong>Rounded Value Output<\/strong>: The result after rounding<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"implementation-details-\">Implementation Details:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uses the <code>Math.Round()<\/code> method to perform precision rounding<\/li>\n\n\n\n<li>Takes an integer parameter to specify the number of decimal places<\/li>\n\n\n\n<li>Returns the rounded value as a float<\/li>\n\n\n\n<li>Uses a lambda expression to connect the rounding function to the output<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"runtime-behavior-\">Runtime Behavior:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When the output value is requested, the node reads both inputs<\/li>\n\n\n\n<li>Applies the Math.Round function with the specified precision<\/li>\n\n\n\n<li>Returns the rounded float value through the output<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"using-the-node\">Using the Node<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the MyRoundToFloatNode to your graph<\/li>\n\n\n\n<li>Connect a float value to the Value input<\/li>\n\n\n\n<li>Set the Decimal places input (e.g., 2 for two decimal places)<\/li>\n\n\n\n<li>Use the Rounded Value output anywhere you need the formatted number<\/li>\n\n\n\n<li>Perfect for display values, currency, or measurements<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4-myvideoplayernode-tutorial\">4. MyVideoPlayerNode Tutorial<\/h2>\n\n\n\n<p>The Video Player Node controls video playback within your application \u2013 perfect for creating interactive media experiences and presentations!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"purpose\">Purpose<\/h3>\n\n\n\n<p>This advanced node allows you to play, stop, and control video playback on GameObjects with video components, supporting both asset-based videos and URL streams.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-by-step-tutorial\">Step-by-Step Tutorial<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1-create-the-node-script\">1. Create the Node Script<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-comment\">\/\/ This is a complex node, so I'll provide a simplified version of the key parts<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyVideoPlayerNode<\/span> : <span class=\"hljs-title\">NodeBase<\/span>, <span class=\"hljs-title\">INodeBase<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">VideoSourceData<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> AssetGuidString = <span class=\"hljs-literal\">null<\/span>;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> VideoUrl = <span class=\"hljs-literal\">null<\/span>;\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_GUID =&gt; <span class=\"hljs-string\">\"c9cfd216-9103-471c-8642-fe07c025e350\"<\/span>;\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_CLASS_NAME =&gt; <span class=\"hljs-string\">\"My Video Player\"<\/span>;\n\n    <span class=\"hljs-comment\">\/\/ Input\/Output definitions with five inputs and two outputs<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_InputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; \n    { \n        NodeFactory.VarType.Flow,  <span class=\"hljs-comment\">\/\/ Play flow<\/span>\n        NodeFactory.VarType.Flow,  <span class=\"hljs-comment\">\/\/ Stop flow<\/span>\n        NodeFactory.VarType.Flow,  <span class=\"hljs-comment\">\/\/ Set Time flow<\/span>\n        NodeFactory.VarType.Float, <span class=\"hljs-comment\">\/\/ Time value<\/span>\n        NodeFactory.VarType.GameObject <span class=\"hljs-comment\">\/\/ Target object<\/span>\n    };\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_OutputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; \n    { \n        NodeFactory.VarType.Flow,  <span class=\"hljs-comment\">\/\/ Execution flow output<\/span>\n        NodeFactory.VarType.Bool   <span class=\"hljs-comment\">\/\/ Is Playing status<\/span>\n    };\n\n    <span class=\"hljs-comment\">\/\/ Input\/Output references<\/span>\n    <span class=\"hljs-keyword\">private<\/span> InputBase m_PlayFlowIn;\n    <span class=\"hljs-keyword\">private<\/span> InputBase m_StopFlowIn;\n    <span class=\"hljs-keyword\">private<\/span> InputBase m_SetTimeFlowIn;\n    <span class=\"hljs-keyword\">private<\/span> InputBase m_TimeFloatIn;\n    <span class=\"hljs-keyword\">private<\/span> InputBase m_GameObjectIn;\n    <span class=\"hljs-keyword\">private<\/span> BoolOutput m_IsPlayingOutput;\n\n    <span class=\"hljs-keyword\">private<\/span> VideoSourceData m_VideoSourceData = <span class=\"hljs-keyword\">new<\/span>();\n\n    <span class=\"hljs-comment\">\/\/ MakeIO method connects the inputs and outputs<\/span>\n    <span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> MakeIO(NodeFileEntry nodeFileEntry)\n    {\n        <span class=\"hljs-comment\">\/\/ Set up flow inputs with their actions<\/span>\n        m_PlayFlowIn = Inputs&#91;<span class=\"hljs-number\">0<\/span>];\n        m_PlayFlowIn.DisplayName = <span class=\"hljs-string\">\"Play\"<\/span>;\n        m_PlayFlowIn.RunAction = () =&gt; Play();\n\n        m_StopFlowIn = Inputs&#91;<span class=\"hljs-number\">1<\/span>];\n        m_StopFlowIn.DisplayName = <span class=\"hljs-string\">\"Stop\"<\/span>;\n        m_StopFlowIn.RunAction = () =&gt; Stop();\n\n        m_SetTimeFlowIn = Inputs&#91;<span class=\"hljs-number\">2<\/span>];\n        m_SetTimeFlowIn.DisplayName = <span class=\"hljs-string\">\"Set Time\"<\/span>;\n        m_SetTimeFlowIn.RunAction = () =&gt; ChangeTime();\n\n        <span class=\"hljs-comment\">\/\/ Set up value inputs<\/span>\n        m_TimeFloatIn = Inputs&#91;<span class=\"hljs-number\">3<\/span>];\n        m_TimeFloatIn.DisplayName = <span class=\"hljs-string\">\"time\"<\/span>;\n\n        m_GameObjectIn = Inputs&#91;<span class=\"hljs-number\">4<\/span>];\n        m_GameObjectIn.DisplayName = <span class=\"hljs-string\">\"object\"<\/span>;\n\n        <span class=\"hljs-comment\">\/\/ Set up outputs<\/span>\n        OutputBase flowOutput = Outputs&#91;<span class=\"hljs-number\">0<\/span>];\n        flowOutput.DisplayName = <span class=\"hljs-string\">\"Run\"<\/span>;\n\n        m_IsPlayingOutput = Outputs&#91;<span class=\"hljs-number\">1<\/span>] as BoolOutput;\n        m_IsPlayingOutput.DisplayName = <span class=\"hljs-string\">\"Is Playing\"<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ Action implementations<\/span>\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> Play()\n    {\n        <span class=\"hljs-comment\">\/\/ Play video on the target object<\/span>\n        <span class=\"hljs-comment\">\/\/ &#91;Implementation details omitted for brevity]<\/span>\n\n        Run(); <span class=\"hljs-comment\">\/\/ Continue execution flow<\/span>\n    }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> Stop()\n    {\n        <span class=\"hljs-comment\">\/\/ Stop video on the target object<\/span>\n    }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> ChangeTime()\n    {\n        <span class=\"hljs-comment\">\/\/ Change playback time to the specified value<\/span>\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-it-works\">How It Works<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"node-properties-\">Node Properties:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Play Input (Flow)<\/strong>: Begins video playback<\/li>\n\n\n\n<li><strong>Stop Input (Flow)<\/strong>: Stops video playback<\/li>\n\n\n\n<li><strong>Set Time Input (Flow)<\/strong>: Sets the playback position<\/li>\n\n\n\n<li><strong>Time Input (Float)<\/strong>: The timestamp to seek to (in seconds)<\/li>\n\n\n\n<li><strong>Object Input (GameObject)<\/strong>: The GameObject containing the video player<\/li>\n\n\n\n<li><strong>Run Output (Flow)<\/strong>: Continues execution flow after playback control<\/li>\n\n\n\n<li><strong>Is Playing Output (Bool)<\/strong>: Indicates if the video is currently playing<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"implementation-details-\">Implementation Details:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Supports both asset-based videos (from your project) and URL-based streaming<\/li>\n\n\n\n<li>Stores video source data that persists when saving the node graph<\/li>\n\n\n\n<li>Connects to Unity&#8217;s VideoPlayer component to control playback<\/li>\n\n\n\n<li>Provides custom UI elements in the node editor for setting video sources<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"advanced-features-\">Advanced Features:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provides IsPlaying status output for conditional logic<\/li>\n\n\n\n<li>Maintains state information even when playback was triggered elsewhere<\/li>\n\n\n\n<li>Has UI in the editor for selecting video assets or entering URLs<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"using-the-node\">Using the Node<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the MyVideoPlayerNode to your graph<\/li>\n\n\n\n<li>Connect the &#8220;object&#8221; input to a GameObject that has a VideoPlayer component<\/li>\n\n\n\n<li>In the node editor, select a video asset or enter a URL<\/li>\n\n\n\n<li>Connect the appropriate flow inputs:\n<ul class=\"wp-block-list\">\n<li>Use &#8220;Play&#8221; to start playback<\/li>\n\n\n\n<li>Use &#8220;Stop&#8221; to end playback<\/li>\n\n\n\n<li>Use &#8220;Set Time&#8221; to jump to a specific timestamp<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Connect the &#8220;Run&#8221; output to any nodes that should execute after video control<\/li>\n\n\n\n<li>Use the &#8220;Is Playing&#8221; boolean output for conditional logic<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"creating-your-own-custom-nodes\">Creating Your Own Custom Nodes<\/h2>\n\n\n\n<p>Now that you&#8217;ve seen several examples, let&#8217;s go through the process of creating your own custom node:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-1-plan-your-node-s-functionality\">Step 1: Plan Your Node&#8217;s Functionality<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Determine what your node will do<\/li>\n\n\n\n<li>Decide what inputs and outputs it needs<\/li>\n\n\n\n<li>Consider any special data it might need to store<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-2-generate-a-unique-guid\">Step 2: Generate a Unique GUID<\/h3>\n\n\n\n<p>Every node needs a unique identifier. Generate a GUID using one of these methods:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Visual Studio&#8217;s Tools &gt; Create GUID<\/li>\n\n\n\n<li>Use an online GUID generator<\/li>\n\n\n\n<li>Execute <code>Guid.NewGuid().ToString()<\/code> in C#<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-3-create-the-node-class\">Step 3: Create the Node Class<\/h3>\n\n\n\n<p>Create a new C# file named after your node (e.g., <code>MyCustomNode.cs<\/code>) with this structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><span class=\"hljs-keyword\">using<\/span> System;\n<span class=\"hljs-keyword\">using<\/span> System.Collections.Generic;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes;\n<span class=\"hljs-keyword\">using<\/span> WorldBuilder.Nodes.IO;\n<span class=\"hljs-keyword\">using<\/span> Worldbuilder.Nodes.FileIO;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">MyNodes<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">MyCustomNode<\/span> : <span class=\"hljs-title\">NodeBase<\/span>\n    {\n        <span class=\"hljs-comment\">\/\/ 1. Define the unique GUID and name<\/span>\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_GUID =&gt; <span class=\"hljs-string\">\"your-generated-guid-here\"<\/span>;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">string<\/span> NODE_CLASS_NAME =&gt; <span class=\"hljs-string\">\"My Custom Node\"<\/span>;\n\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> Guid NodeClassGuid =&gt; Guid.Parse(NODE_GUID);\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> NodeClassName =&gt; NODE_CLASS_NAME;\n\n        <span class=\"hljs-comment\">\/\/ 2. Define inputs and outputs<\/span>\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; InputTypes =&gt; m_InputTypes;\n        <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; OutputTypes =&gt; m_OutputTypes;\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_InputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; {\n            <span class=\"hljs-comment\">\/\/ List your input types here<\/span>\n        };\n\n        <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> List&lt;NodeFactory.VarType&gt; m_OutputTypes = <span class=\"hljs-keyword\">new<\/span> List&lt;NodeFactory.VarType&gt; {\n            <span class=\"hljs-comment\">\/\/ List your output types here<\/span>\n        };\n\n        <span class=\"hljs-comment\">\/\/ 3. Create references to inputs and outputs<\/span>\n        <span class=\"hljs-keyword\">private<\/span> InputBase m_SomeInput;\n        <span class=\"hljs-keyword\">private<\/span> FloatOutput m_SomeOutput;\n\n        <span class=\"hljs-comment\">\/\/ 4. Create constructors<\/span>\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyCustomNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, Guid nodeInstanceGuid<\/span>) :\n            <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeInstanceGuid, <span class=\"hljs-literal\">null<\/span>, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">MyCustomNode<\/span>(<span class=\"hljs-params\">NodeTree nodeTree, NodeFile nodeFile, NodeFileEntry nodeFileEntry<\/span>) :\n            <span class=\"hljs-title\">base<\/span>(<span class=\"hljs-params\">nodeTree, nodeFileEntry.Identity, nodeFileEntry, m_InputTypes, m_OutputTypes<\/span>)\n        <\/span>{\n            <span class=\"hljs-comment\">\/\/ Load any saved data if needed<\/span>\n        }\n\n        <span class=\"hljs-comment\">\/\/ 5. Configure inputs and outputs<\/span>\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">protected<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MakeIO<\/span>(<span class=\"hljs-params\">NodeFileEntry nodeFileEntry<\/span>)\n        <\/span>{\n            <span class=\"hljs-comment\">\/\/ Configure inputs<\/span>\n            m_SomeInput = Inputs&#91;<span class=\"hljs-number\">0<\/span>];\n            m_SomeInput.DisplayName = <span class=\"hljs-string\">\"My Input\"<\/span>;\n\n            <span class=\"hljs-comment\">\/\/ For flow inputs, assign the action<\/span>\n            <span class=\"hljs-keyword\">if<\/span> (InputTypes&#91;<span class=\"hljs-number\">0<\/span>] == NodeFactory.VarType.Flow)\n                Inputs&#91;<span class=\"hljs-number\">0<\/span>].RunAction = MyAction;\n\n            <span class=\"hljs-comment\">\/\/ Configure outputs<\/span>\n            m_SomeOutput = Outputs&#91;<span class=\"hljs-number\">0<\/span>] <span class=\"hljs-keyword\">as<\/span> FloatOutput;\n            m_SomeOutput.DisplayName = <span class=\"hljs-string\">\"My Output\"<\/span>;\n            m_SomeOutput.SetGetValueFunc(CalculateOutput);\n        }\n\n        <span class=\"hljs-comment\">\/\/ 6. Implement node functionality<\/span>\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">MyAction<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-comment\">\/\/ Your node's action logic here<\/span>\n\n            <span class=\"hljs-comment\">\/\/ Continue execution flow<\/span>\n            Run();\n        }\n\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">float<\/span> <span class=\"hljs-title\">CalculateOutput<\/span>(<span class=\"hljs-params\"><\/span>)\n        <\/span>{\n            <span class=\"hljs-comment\">\/\/ Your calculation logic here<\/span>\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">0.0<\/span>f;\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"step-4-test-your-node\">Step 4: Test Your Node<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add your new node to your project<\/li>\n\n\n\n<li>Use it in a node graph<\/li>\n\n\n\n<li>Test all inputs and outputs to verify functionality<\/li>\n\n\n\n<li>Debug any issues using Unity&#8217;s console<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"best-practices-for-custom-nodes\">Best Practices for Custom Nodes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"1-keep-it-simple\">1. Keep It Simple<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Focus each node on a specific, well-defined task<\/li>\n\n\n\n<li>Avoid creating &#8220;super nodes&#8221; that try to do too many things<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"2-use-descriptive-names\">2. Use Descriptive Names<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Give your node a clear, descriptive name<\/li>\n\n\n\n<li>Use display names that explain what each input and output does<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"3-handle-edge-cases\">3. Handle Edge Cases<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check for null values and other potential errors<\/li>\n\n\n\n<li>Provide sensible defaults when inputs are not connected<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"4-document-your-nodes\">4. Document Your Nodes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add comments explaining complex logic<\/li>\n\n\n\n<li>Consider creating a README for your custom node library<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"5-optimize-performance\">5. Optimize Performance<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Avoid expensive operations in frequently called methods<\/li>\n\n\n\n<li>Cache results when appropriate to avoid redundant calculations<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>Custom nodes are a powerful way to extend your node-based application with new functionality. By following the patterns shown in these examples, you can create your own nodes that integrate seamlessly with the existing system.<\/p>\n\n\n\n<p>Remember that the key elements of any node are:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A unique GUID to identify the node type<\/li>\n\n\n\n<li>Clearly defined inputs and outputs<\/li>\n\n\n\n<li>Well-implemented functionality<\/li>\n\n\n\n<li>Proper execution flow management<\/li>\n<\/ol>\n\n\n\n<p>Happy node creating!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. MyDebugNode Tutorial The Debug Node lets you print messages to the Unity console \u2013 perfect for tracking values and debugging your node graphs during runtime! You can find all of our currently implemented Nodes here. Purpose This node takes a string input and logs it to the Unity console, making it easy to debug&#8230;<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"doc_category":[16],"doc_tag":[],"class_list":["post-1530","docs","type-docs","status-publish","hentry","doc_category-world-builder-extensions"],"year_month":"2025-08","word_count":2400,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"maximilian.winter","author_nicename":"maximilian-winter","author_url":"https:\/\/www.portalsunited.com:443\/author\/maximilian-winter\/"},"doc_category_info":[{"term_name":"World Builder - Extensions","term_url":"https:\/\/www.portalsunited.com:443\/docs-category\/world-builder-extensions\/"}],"doc_tag_info":[],"_links":{"self":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/comments?post=1530"}],"version-history":[{"count":3,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1530\/revisions"}],"predecessor-version":[{"id":1685,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/docs\/1530\/revisions\/1685"}],"wp:attachment":[{"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/media?parent=1530"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/doc_category?post=1530"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/www.portalsunited.com:443\/wp-json\/wp\/v2\/doc_tag?post=1530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}