Creating Custom Node
Welcome to Portals United! / Forums / Troubleshooting / Creating Custom Node
- This topic has 2 replies, 3 voices, and was last updated 3 days, 10 hours ago by
robert.malzan.
-
AuthorPosts
-
June 17, 2025 at 3:28 pm #1768
Hello Robert
I was writing code to create my custom node that can communicate to chatGpt. but it gave me lots of errors. then I tried to duplicate the web request node first with different name and GUID but it is giving me this error of reference
[CS0012] ChatWithAINode.cs(353,45): The type ‘WWWForm’ is defined in an assembly that is not referenced. You must add a reference to assembly
‘UnityEngine.UnityWebRequestModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null’.
Here is my script:
using System; using System.Collections; using System.Collections.Generic; using Newtonsoft.Json; using UnityEngine; using UnityEngine.UIElements; using Worldbuilder.Nodes.FileIO; using WorldBuilder.Nodes.IO; using WorldBuilder.Signals; using WorldBuilder.UI; using Nuro.Processes; namespace WorldBuilder.Nodes { public class ChatWithAINode : NodeBase, INodeBase { public static string NODE_GUID => "7d0c45bc-df5a-4d38-821b-b494d3915359"; public static string NODE_CLASS_NAME => "ChatGpt"; public override Guid NodeClassGuid => Guid.Parse( NODE_GUID ); public override string NodeClassName => NODE_CLASS_NAME; public static List < NodeFactory.VarType > InputTypes => m_InputTypes; public static List < NodeFactory.VarType > OutputTypes => m_OutputTypes; private static List < NodeFactory.VarType > m_InputTypes = new List < NodeFactory.VarType > { NodeFactory.VarType.Flow, NodeFactory.VarType.String, NodeFactory.VarType.String }; private static List < NodeFactory.VarType > m_OutputTypes = new List < NodeFactory.VarType > { NodeFactory.VarType.Flow, NodeFactory.VarType.Flow, NodeFactory.VarType.Flow, NodeFactory.VarType.String }; private InputBase m_FlowInput; private InputBase m_HeaderInput; private InputBase m_PayloadInput; private OutputBase m_FlowOutput; private OutputBase m_SuccessFlowOut; private OutputBase m_ErrorFlowOut; private StringOutput m_ResultOut; public class Params { public string MessageType; public string Url; } private Params m_Params = new(); private List < string > m_MessageTypes = new() { WebRequestProcess.MethodTypes.POST.ToString(), WebRequestProcess.MethodTypes.GET.ToString(), WebRequestProcess.MethodTypes.PATCH.ToString(), WebRequestProcess.MethodTypes.DELETE.ToString(), }; private DropdownField m_ListView; private TextField m_UrlTextField; private string m_Result = ""; public ChatWithAINode( NodeTree nodeTree, Guid nodeInstanceGuid ) : base( nodeTree, nodeInstanceGuid ) { m_Params = new Params() { MessageType = "POST", Url = "http: //mydomain /myendpoint" }; MakeIO( NodeInstanceGuid, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID, Guid.NewGuid(), NodeTree.INVALID_GUID ); } public ChatWithAINode( NodeTree nodeTree, NodeFile nodeFile, NodeFileEntry nodeFileEntry ) : base( nodeTree, nodeFileEntry.Identity ) { string messageData = nodeFileEntry.ExtraDataStringId != NodeTree.INVALID_GUID ? nodeFile.StringList[nodeFileEntry.ExtraDataStringId] : ""; if ( string.IsNullOrEmpty( messageData ) ) { m_Params = new Params() { MessageType = "POST", Url = "http: //mydomain /myendpoint" }; } else { m_Params = JsonConvert.DeserializeObject < Params >( messageData ); } MakeIO( nodeFileEntry.Identity, nodeFileEntry.Inputs[0].Identity, nodeFileEntry.Inputs[0].ConnectionGuid, nodeFileEntry.Inputs[1].Identity, nodeFileEntry.Inputs[1].ConnectionGuid, nodeFileEntry.Inputs[2].Identity, nodeFileEntry.Inputs[2].ConnectionGuid, nodeFileEntry.Outputs[0].Identity, nodeFileEntry.Outputs[0].ConnectionGuid, nodeFileEntry.Outputs[1].Identity, nodeFileEntry.Outputs[1].ConnectionGuid, nodeFileEntry.Outputs[2].Identity, nodeFileEntry.Outputs[2].ConnectionGuid, nodeFileEntry.Outputs[3].Identity, nodeFileEntry.Outputs[3].ConnectionGuid ); GroupGuid = nodeFileEntry.GroupGuid; } void MakeIO( Guid nodeInstanceGuid, Guid flowInputId, Guid flowInputRef, Guid headerInputId, Guid headerInputRef, Guid payloadInputId, Guid payloadInputRef, Guid flowOutputId, Guid flowOutputRef, Guid successFlowOutId, Guid successFlowOutRef, Guid errorFlowOutId, Guid errorFlowOutRef, Guid resultOutputId, Guid resultOutputRef ) { m_FlowInput = new InputBase( NodeTree, nodeInstanceGuid, flowInputId, "", NodeFactory.VarType.Flow, SYMBOL_FLOW ); m_FlowInput.OutputReference = flowInputRef; m_FlowInput.RunAction = RunAction; Inputs.Add( m_FlowInput ); m_HeaderInput = new InputBase( NodeTree, nodeInstanceGuid, headerInputId, "Header", NodeFactory.VarType.String ); m_HeaderInput.OutputReference = headerInputRef; Inputs.Add( m_HeaderInput ); m_PayloadInput = new InputBase( NodeTree, nodeInstanceGuid, payloadInputId, "Payload", NodeFactory.VarType.String ); m_PayloadInput.OutputReference = payloadInputRef; Inputs.Add( m_PayloadInput ); // OUTPUTS ------------------------------------------ m_FlowOutput = new OutputBase( NodeTree, nodeInstanceGuid, flowOutputId, "", NodeFactory.VarType.Flow, SYMBOL_FLOW); m_FlowOutput.InputReference = flowOutputRef; Outputs.Add(m_FlowOutput); m_SuccessFlowOut = new OutputBase( NodeTree, nodeInstanceGuid, successFlowOutId, "on success", NodeFactory.VarType.Flow, SYMBOL_FLOW ); m_SuccessFlowOut.InputReference = successFlowOutRef; Outputs.Add( m_SuccessFlowOut ); m_ErrorFlowOut = new OutputBase( NodeTree, nodeInstanceGuid, errorFlowOutId, "on error", NodeFactory.VarType.Flow, SYMBOL_FLOW ); m_ErrorFlowOut.InputReference = errorFlowOutRef; Outputs.Add( m_ErrorFlowOut ); m_ResultOut = new StringOutput( NodeTree, nodeInstanceGuid, resultOutputId, GetValue); m_ResultOut.InputReference = resultOutputRef; m_ResultOut.DisplayName = "Value"; Outputs.Add( m_ResultOut ); } private int MessageTypeIndex( string messageType ) { int ix = 0; foreach ( string s in m_MessageTypes ) { if ( s == messageType ) return ix; ix++; } return 0; } WebRequestProcess.MethodTypes StringToMethodType( string method ) { if ( Enum.TryParse < WebRequestProcess.MethodTypes >( method, out WebRequestProcess.MethodTypes mType ) ) { return mType; } else { return WebRequestProcess.MethodTypes.POST; } } #if !HOPPER public override void InsertVisual( NodeTreeVisualizer visualizer, VisualElement root, Vector2 position ) { base.InsertVisual( visualizer, root, position ); int msgIndex = MessageTypeIndex( m_Params.MessageType ); m_ListView = NodeTree.ReferenceProvider.ElementFactory.CreateDropdownField( null, "", m_MessageTypes, msgIndex, UI.DropdownStyles.NodeEditor | UI.DropdownStyles.NodeEditorCentered | UI.DropdownStyles.NodeEditorMargin ); m_ListView.RegisterCallback < ChangeEvent < string > >( OnMethodChanged ); m_NodeBox.Insert( 1, m_ListView ); m_UrlTextField = NodeTree.ReferenceProvider.ElementFactory.CreateTextField( null, "URL", TextFieldStyles.NodeEditor, "", "enter URL to call" ); m_UrlTextField.value = m_Params.Url; m_UrlTextField.RegisterCallback < ChangeEvent < string > >( OnUrlChanged ); m_NodeBox.Insert( 2, m_UrlTextField ); } protected virtual void OnUrlChanged( ChangeEvent < string > e ) { m_Params.Url = e.newValue; } protected virtual void OnMethodChanged( ChangeEvent < string > e ) { m_Params.MessageType = e.newValue; } public override string GetExtraData() { return JsonConvert.SerializeObject( m_Params ); } public override void SetExtraData( string extraData ) { m_Params = JsonConvert.DeserializeObject<Params>( extraData ); } #endif private void RunAction() { SendWebRequest(); Run(); } private string GetValue() { return m_Result; } private void SendWebRequest() { if ( !Uri.IsWellFormedUriString( m_Params.Url, UriKind.Absolute ) ) { m_Result = $"invalid URL!! ({m_Params.Url})"; RunFlowOutput( m_ErrorFlowOut ); return; } Dictionary <string, string> headers = new Dictionary<string, string>(); string payload = null; if (m_PayloadInput.HasValidConnection()) payload = m_PayloadInput.GetString(); headers["Content-Type" ] = "application/json"; headers["accept" ] = "*/*"; if ( m_HeaderInput.HasValidConnection() ) { string token = m_HeaderInput.GetString(); headers["Authorization"] = token.StartsWith( "Bearer " ) ? token : "Bearer " + token; } WebRequestProcess process = new WebRequestProcess( StringToMethodType( m_Params.MessageType), "Node WebRequest", m_Params.Url, payload, headers, null); process.onFinished += ( status ) => { m_Result = process.Result; RunFlowOutput( status != Process.ProcessStatus.Succeeded ? m_ErrorFlowOut : m_SuccessFlowOut ); }; process.Start(); } } }
June 18, 2025 at 2:13 pm #1781I pushed this issue to a colleague of mine who is our expert for runtime scripting. He’s already on it. I am also working to improve our WebRequest Node to be more flexible. Maybe this will also help.
-
AuthorPosts
- You must be logged in to reply to this topic.