{"id":1119,"date":"2022-07-02T16:48:09","date_gmt":"2022-07-02T07:48:09","guid":{"rendered":"https:\/\/colory-games.net\/site\/?p=1119"},"modified":"2023-11-04T20:48:02","modified_gmt":"2023-11-04T11:48:02","slug":"create-your-own-blueprint-node-by-inheriting-k2node-3-menu-en","status":"publish","type":"post","link":"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-3-menu-en\/","title":{"rendered":"[UE5] Create Your Own Blueprint Node by Inheriting K2Node (3) Menu"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>This article explains how to add a menu by right-clicking a Blueprint node.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/sequence_node_menu.png?ssl=1\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/sequence_node_menu.png?ssl=1\" alt=\"Menu for node &quot;Sequence&quot;\" data-recalc-dims=\"1\"><\/a><\/p>\n<p>This article assumes that you are familiar with the basic contents of creating the Blueprint node.<br>\nPlease check <a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-1-basic-en\/\">the Basic article<\/a> and <a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-2-execution-pin-en\/\">the Execution Pin article<\/a> if necessary.<\/p>\n<ul>\n<li><a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-1-basic-en\/\">Create Your Own Blueprint Node by Inheriting K2Node (1) Basic<\/a><\/li>\n<li><a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-2-execution-pin-en\/\">Create Your Own Blueprint Node by Inheriting K2Node (2) Execution Pin<\/a><\/li>\n<li>Create Your Own Blueprint Node by Inheriting K2Node (3) Menu &lt;&#8212; This article<\/li>\n<li><a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-4-ui-en\/\">Create Your Own Blueprint Node by Inheriting K2Node (4) UI<\/a><\/li>\n<\/ul>\n<div id=\"toc_container\" class=\"no_bullets\"><p class=\"toc_title\">\u76ee\u6b21<\/p><ul class=\"toc_list\"><li><a href=\"#Source_Code\">Source Code<\/a><\/li><li><a href=\"#Specification_of_the_Blueprint_Node\">Specification of the Blueprint Node<\/a><\/li><li><a href=\"#Create_a_Module\">Create a Module<\/a><\/li><li><a href=\"#Create_a_Blueprint_Node\">Create a Blueprint Node<\/a><ul><li><a href=\"#3_Add_Pins\">3. Add Pins<\/a><\/li><li><a href=\"#4_Define_the_Process_of_Execution_Pins\">4. Define the Process of Execution Pins<\/a><\/li><li><a href=\"#5_Add_Menu\">5. Add Menu<\/a><\/li><\/ul><\/li><li><a href=\"#Use_the_Created_Node\">Use the Created Node<\/a><\/li><\/ul><\/div>\n<h1><span id=\"Source_Code\">Source Code<\/span><\/h1>\n<p>The complete source code is available on GitHub.<\/p>\n<p><a href=\"https:\/\/github.com\/colory-games\/techblog-sample-projects\/tree\/main\/nutti\/20220702\">https:\/\/github.com\/colory-games\/techblog-sample-projects\/tree\/main\/nutti\/20220702<\/a><\/p>\n<p>To run the source code, follow these steps.<\/p>\n<ol>\n<li>Place the directory <code>MyManualSwitch<\/code> into <code>Plugins<\/code> in your Unreal Engine project directory.<\/li>\n<li>Right click on the <code>.uproject<\/code> file and create a project file for Visual Studio.<\/li>\n<li>Open the project file and build the project.<\/li>\n<li>Run Unreal Engine from the <code>.uproject<\/code> file and activate the &quot;MyManualSwitch&quot; plugin.<\/li>\n<\/ol>\n<h1><span id=\"Specification_of_the_Blueprint_Node\">Specification of the Blueprint Node<\/span><\/h1>\n<p>The specification of the Blueprint node &quot;MyManualSwitch&quot; is as follows.<\/p>\n<ul>\n<li>Add execution pins &quot;A&quot; and &quot;B&quot; on the output side.<\/li>\n<li>Add a menu when you right-click on a node.\n<ul>\n<li>&quot;Execute A&quot;: Execute execution pin &quot;A&quot;.<\/li>\n<li>&quot;Execute B&quot;: Execute execution pin &quot;B&quot;.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h1><span id=\"Create_a_Module\">Create a Module<\/span><\/h1>\n<p>Create a module by following to the description in the Basic section.<br>\nFor the concreate instructions to create a module, please refer to the <a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-1-basic-en\/\">article for the basic<\/a>.<\/p>\n<h1><span id=\"Create_a_Blueprint_Node\">Create a Blueprint Node<\/span><\/h1>\n<p>We can create a Blueprint node by the following steps.<\/p>\n<ol>\n<li>Inherit class <code>UK2Node<\/code>.<\/li>\n<li>Setup basic information.<\/li>\n<li>Add pins.<\/li>\n<li>Define the process of execution pins.<\/li>\n<li>Add menu.<\/li>\n<\/ol>\n<p>Steps 1 and 2 are the almost same as in the <a href=\"https:\/\/colory-games.net\/site\/en\/create-your-own-blueprint-node-by-inheriting-k2node-1-basic-en\/\">article for the basic<\/a>, so we will start from step 3.<\/p>\n<h2><span id=\"3_Add_Pins\">3. Add Pins<\/span><\/h2>\n<p>Add the following pins to meet the specifications of the node.<\/p>\n<table>\n<thead>\n<tr>\n<th><strong>Pin Name<\/strong><\/th>\n<th><strong>Input\/Output<\/strong><\/th>\n<th><strong>Role<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><\/td>\n<td>Input<\/td>\n<td>Execution the node.<\/td>\n<\/tr>\n<tr>\n<td>A<\/td>\n<td>Output<\/td>\n<td>Execute the node connected to this pin when the internal pin &quot;Switch&quot; is <code>True<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>B<\/td>\n<td>Output<\/td>\n<td>Execute the node connected to this pin when the internal pin &quot;Switch&quot; is <code>False<\/code>.<\/td>\n<\/tr>\n<tr>\n<td>Switch<\/td>\n<td>(Internal)<\/td>\n<td>Execute the node connected to the execution pin &quot;A&quot; if <code>True<\/code>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We will implement the process of adding pins to <code>AllocateDefaultPins<\/code>.<\/p>\n<pre><code class=\"language-cpp\">CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);\nCreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, APinName);\nCreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, BPinName);\n\/\/ Create an internal pin.\nUEdGraphPin* SwitchPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Boolean, SwitchPinName);\nSwitchPin->DefaultValue = &quot;true&quot;;\nSwitchPin->bHidden = true;\nSwitchPin->bDefaultValueIsReadOnly = true;\nSwitchPin->bNotConnectable = true;\n<\/code><\/pre>\n<p>Note that we add an internal pin &quot;Switch&quot; that holds a flag to switch the execution pin to execute.<br>\nBy specifying the value <code>&quot;true&quot;<\/code> to the member variable <code>DefaultValue<\/code>, we can set the default value <code>true<\/code>.<\/p>\n<h2><span id=\"4_Define_the_Process_of_Execution_Pins\">4. Define the Process of Execution Pins<\/span><\/h2>\n<p>Define the process for the execution pin.<br>\nThe node &quot;MyManualSwitch&quot; executes the node connected to the pin &quot;A&quot; when the internal pin &quot;Switch&quot; is <code>True<\/code>. If <code>False<\/code>, execute the node connected to the pin &quot;B&quot;.<br>\nTo implement this, we define the Blueprint compilation process.<\/p>\n<p>The following is the Blueprint compilation process defined in the member function <code>Compile<\/code>.<\/p>\n<pre><code class=\"language-cpp\">UK2Node_MyManualSwitch* MyManualSwitchNode = CastChecked(Node);\nUEdGraphPin* APin = MyManualSwitchNode->FindPin(APinName);\nUEdGraphPin* BPin = MyManualSwitchNode->FindPin(BPinName);\n\/\/ Get the internal pin &quot;Switch&quot;.\nUEdGraphPin* SwitchPin = MyManualSwitchNode->FindPin(SwitchPinName);\nUEdGraphPin* SwitchNet = FEdGraphUtilities::GetNetFromPin(SwitchPin);\nFBPTerminal* Switch = Context.NetMap.FindRef(SwitchNet);\n\/\/ Transfer the control flow to the execution pin &quot;B&quot; when the value of the internal pin &quot;Switch&quot; is false.\nFBlueprintCompiledStatement&amp; GotoStatement = Context.AppendStatementForNode(MyManualSwitchNode);\nGotoStatement.Type = KCST_GotoIfNot;\nGotoStatement.LHS = Switch;\nContext.GotoFixupRequestMap.Add(&amp;GotoStatement, BPin);\n\/\/ Transfer the control flow to the execution pin &quot;A&quot; when the value of the internal pin &quot;Switch&quot; is true.\nGenerateSimpleThenGoto(Context, *MyManualSwitchNode, APin);\n<\/code><\/pre>\n<p>By creating a statement of type <code>KCST_GotoIfNot<\/code> and passing the variable of the internal pin &quot;Switch&quot; to the <code>LHS<\/code> of the statement <code>FBlueprintCompiledStatement<\/code>, we can implement the process for the execution pin &quot;B&quot;.<br>\nThe process of transferring execution control to the execution pin &quot;A&quot; is defined by calling the function <code>GenerateSimpleThenGoto<\/code>.<\/p>\n<h2><span id=\"5_Add_Menu\">5. Add Menu<\/span><\/h2>\n<p>We will explain how to add items to the menu that appears when you right-click on the node &quot;MyManualSwitch&quot;.<br>\nNote that the menu depends on the status of the internal pin &quot;Switch&quot;.<\/p>\n<ul>\n<li>&quot;Execute A&quot;: Execute execution pin &quot;A&quot;.<\/li>\n<li>&quot;Execute B&quot;: Execute execution pin &quot;B<\/li>\n<\/ul>\n<p>To add an item to the menu, override the member function <code>GetNodeContextMenuActions<\/code> and define the process to add the item.<\/p>\n<pre><code class=\"language-cpp\">void UK2Node_MyManualSwitch::GetNodeContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const\n{\n    Super::GetNodeContextMenuActions(Menu, Context);\n    FToolMenuSection&amp; Section = Menu->AddSection(&quot;K2NodeMyManualSwitch&quot;, NSLOCTEXT(&quot;K2Node&quot;, &quot;MyManualSwitchHeader&quot;, &quot;My Manual Switch&quot;));\n    \/\/ Get the value of the internal pin &quot;Switch&quot;.\n    UEdGraphPin* Pin = FindPin(SwitchPinName);\n    bool bExecuteB = Pin->GetDefaultAsString() == &quot;true&quot;;\n    if (!bExecuteB)\n    {\n        \/\/ Add menu item &quot;Execute A&quot;.\n        Section.AddMenuEntry(\n            &quot;ExecuteA&quot;,\n            LOCTEXT(&quot;ExecuteA&quot;, &quot;Execute A&quot;),\n            LOCTEXT(&quot;ExecuteATooltip&quot;, &quot;Switch to execute A pin&quot;),\n            FSlateIcon(),\n            FUIAction(FExecuteAction::CreateUObject(const_cast(this), &amp;UK2Node_MyManualSwitch::ToggleSwitch)));\n    }\n    else\n    {\n        \/\/ Add menu item &quot;Execute B&quot;.\n        Section.AddMenuEntry(\n            &quot;ExecuteB&quot;,\n            LOCTEXT(&quot;ExecuteB&quot;, &quot;Execute B&quot;),\n            LOCTEXT(&quot;ExecuteBTooltip&quot;, &quot;Switch to execute B pin&quot;),\n            FSlateIcon(),\n            FUIAction(FExecuteAction::CreateUObject(const_cast(this), &amp;UK2Node_MyManualSwitch::ToggleSwitch)));\n    }\n}\n<\/code><\/pre>\n<p>First, add a menu section (structure <code>FToolMenuSection<\/code>) by calling the member function <code>AddSection<\/code> of <code>UToolMenu<\/code>.<br>\nThen, get the value of the internal pin &quot;Switch&quot; and add a menu item by calling the member function <code>AddMenuEntry<\/code> of the structure <code>FToolMenuSection<\/code>.<br>\nNote that the menu item is changed depending on the value of the internal pin <code>Switch<\/code>.<\/p>\n<p>The 5th argument of the member function <code>AddSection<\/code> is the member function <code>ToggleSwitch<\/code> that defines the process of switching the value of the internal pin <code>Switch<\/code> from <code>&quot;true&quot;<\/code> to <code>&quot;false&quot;<\/code> or vice versa.<br>\nThe member function <code>ToggleSwitch<\/code> is defined as follows.<\/p>\n<pre><code class=\"language-cpp\">void UK2Node_MyManualSwitch::ToggleSwitch()\n{\n    Modify();\n    \/\/ Change the value of the internal pin &quot;Switch&quot;.\n    UEdGraphPin* Pin = FindPin(SwitchPinName);\n    if (Pin->GetDefaultAsString() == &quot;true&quot;)\n    {\n        Pin->DefaultValue = &quot;false&quot;;\n    }\n    else\n    {\n        Pin->DefaultValue = &quot;true&quot;;\n    }\n    \/\/ Notify the data changes to the Blueprint editor.\n    FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint());\n}\n<\/code><\/pre>\n<p>This member function checks the current value of the internal pin <code>Switch<\/code> and set the opposite of the current value.<\/p>\n<p>Finally, the function <code>FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified<\/code> is called to notify the Blueprint asset changes to the Blueprint editor.<br>\nThis function needs to be called, to update the Blueprint editor to the latest state.<\/p>\n<h1><span id=\"Use_the_Created_Node\">Use the Created Node<\/span><\/h1>\n<p>Let&#8217;s use the node you created.<br>\nOpen the Blueprint Editor, right-click to display the menu, and enter &quot;mymaualswitch&quot; in the search box.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_search.png?ssl=1\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_search.png?ssl=1\" alt=\"Search for node &quot;MyManualSwitch&quot;\" data-recalc-dims=\"1\"><\/a><\/p>\n<p>Select and place the node &quot;MyManualSwitch&quot; in the category &quot;Flow Control&quot;.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_build_actor.png?ssl=1\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_build_actor.png?ssl=1\" alt=\"Create Actor\" data-recalc-dims=\"1\"><\/a><\/p>\n<p>When the created Actor is placed in the level, we can see that the execution pin will be changed depending on the value of the internal pin &quot;Switch&quot;.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_menu.png?ssl=1\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_menu.png?ssl=1\" alt=\"Menu of node &quot;MyManualSwitch&quot;\" data-recalc-dims=\"1\"><\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This article explains how to add a menu when right-clicking a custom node.  <\/p>\n","protected":false},"author":2,"featured_media":609,"comment_status":"open","ping_status":"open","sticky":false,"template":"templates\/single-home-techblog.php","format":"standard","meta":{"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":false,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[154,71],"tags":[177],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/i0.wp.com\/colory-games.net\/site\/wp-content\/uploads\/tech-blog\/nutti\/2022\/07\/20220702\/use_custom_node_menu.png?fit=481%2C679&ssl=1","_links":{"self":[{"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/posts\/1119"}],"collection":[{"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/comments?post=1119"}],"version-history":[{"count":5,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/posts\/1119\/revisions"}],"predecessor-version":[{"id":1151,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/posts\/1119\/revisions\/1151"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/media\/609"}],"wp:attachment":[{"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/media?parent=1119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/categories?post=1119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/colory-games.net\/site\/wp-json\/wp\/v2\/tags?post=1119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}