A game about forced loneliness, made by TACStudios
1# Custom C# node attributes reference
2
3You can add attributes to a node class and port variable definitions to customize the look of a Custom C# node.
4
5## Node class attributes
6
7You can customize the titles that appear on a node, where it appears in the fuzzy finder, and its icon. Node class attributes must be placed above the node class definition in a node's C# script.
8
9Visual Scripting has 5 node class attributes:
10
11- [UnitTitle](#unittitle)
12- [UnitShortTitle](#unitshorttitle)
13- [UnitSubtitle](#unitsubtitle)
14- [UnitCategory](#unitcategory)
15- [TypeIcon](#typeicon)
16
17
18Usually, Visual Scripting automatically applies any changes you make to a node's class attributes after you save the C# file.
19
20### UnitTitle
21
22
23
24You can specify a `[UnitTitle]` to display a different title than the node's class name on the node when it appears in a Script Graph, and when you view details about the node in the Graph Inspector:
25
26```C#
27using System;
28using Unity.VisualScripting;
29using UnityEngine;
30
31
32[UnitTitle("My New Title")]
33public class MyNodeAfter : Unit
34{
35 ...
36
37 }
38}
39```
40
41The `[UnitTitle]` attribute overrides the node's class name.
42
43### UnitShortTitle
44
45
46
47You can specify a `[UnitShortTitle]` to display a different title on the node when it appears in a Script Graph:
48
49```C#
50using System;
51using Unity.VisualScripting;
52using UnityEngine;
53
54
55[UnitShortTitle("Short Title")]
56[UnitTitle("My New Title")]
57public class MyNodeAfter : Unit
58{
59 ...
60
61 }
62}
63```
64
65The `[UnitShortTitle]` only appears on the node in a Script Graph. The `[UnitTitle]` or node class name still displays in the Graph Inspector.
66
67### UnitSubtitle
68
69
70
71You can add a `[UnitSubtitle]` to add a line of text below the `[UnitTitle]`, `[UnitShortTitle]`, or node class name when a node appears in a Script Graph:
72
73```C#
74using System;
75using Unity.VisualScripting;
76using UnityEngine;
77
78
79[UnitSubtitle("It's a subtitle!")]
80[UnitShortTitle("Short Title")]
81[UnitTitle("My New Title")]
82public class MyNodeAfter : Unit
83{
84 ...
85
86 }
87}
88```
89
90The `[UnitSubtitle]` doesn't appear in the Graph Inspector.
91
92### UnitCategory
93
94
95
96You can specify a `[UnitCategory]` to tell Visual Scripting where to place the node in the fuzzy finder:
97
98```C#
99using System;
100using Unity.VisualScripting;
101using UnityEngine;
102
103
104[UnitCategory("FirstLevel/SecondLevel")]
105public class MyNodeAfter : Unit
106{
107 ...
108
109 }
110}
111```
112
113Replace `FirstLevel` with the name of the top-level category in the fuzzy finder where you want Visual Scripting to place the node. Replace `SecondLevel` with the name of a subcategory. Visual Scripting creates the categories if they don't already exist in the fuzzy finder.
114
115> [!NOTE]
116> You must [regenerate your Node Library](vs-configuration.md) for changes made to a node's `[UnitCategory]` to take effect.
117
118### TypeIcon
119
120
121
122You can use the `[TypeIcon]` attribute to change the icon that appears on a node when it appears in a Script Graph:
123
124```C#
125using System;
126using Unity.VisualScripting;
127using UnityEngine;
128
129
130[TypeIcon(typeof(ToggleValue))]
131public class MyNodeAfter : Unit
132{
133 ...
134
135 }
136}
137```
138The icon for the node changes in the Graph Inspector, too.
139
140> [!NOTE]
141> You can't point to your own custom icons from this attribute. You must use an icon from the Visual Scripting icons library, which includes all Unity types.
142
143
144## Port attributes
145
146Custom nodes have one mandatory port attribute and one optional port attribute: [DoNotSerialize](#donotserialize) and [PortLabelHidden](#portlabelhidden), respectively. Port attributes must be placed above your variable declarations for each port variable in the node.
147
148Visual Scripting automatically applies any changes you make to a node's port attributes after you save the script file.
149
150### DoNotSerialize
151
152`[DoNotSerialize]` is a mandatory attribute for all ports on custom nodes. Add this attribute to avoid serialization of data that shouldn't be serialized:
153
154```C#
155using System;
156using Unity.VisualScripting;
157using UnityEngine;
158
159
160[UnitShortTitle("Short Title")]
161[UnitTitle("My New Title")]
162[UnitCategory("My Nodes")]
163[UnitSubtitle("It's a subtitle!")]
164[TypeIcon(typeof(Color))]
165
166public class MyNodeAfter : Unit
167{
168 [DoNotSerialize]
169 public ControlInput inputTrigger;
170
171 [DoNotSerialize]
172 public ControlOutput outputTrigger;
173
174 [DoNotSerialize]
175 public ValueInput myValueA;
176
177 [DoNotSerialize]
178 public ValueInput myValueB;
179
180 [DoNotSerialize]
181 public ValueOutput result;
182
183 private string resultValue;
184
185 protected override void Definition()
186 {
187 ...
188 }
189}
190```
191
192### PortLabelHidden
193
194
195
196You can add the `[PortLabelHidden]` attribute to hide the name label for any port on a node when it appears in a Script Graph:
197
198```C#
199using System;
200using Unity.VisualScripting;
201using UnityEngine;
202
203
204[UnitShortTitle("Short Title")]
205[UnitTitle("My New Title")]
206[UnitCategory("My Nodes")]
207[UnitSubtitle("It's a subtitle!")]
208[TypeIcon(typeof(Color))]
209
210public class MyNodeAfter : Unit
211{
212 [DoNotSerialize]
213 [PortLabelHidden]
214 public ControlInput inputTrigger;
215
216 [DoNotSerialize]
217 [PortLabelHidden]
218 public ControlOutput outputTrigger;
219
220 [DoNotSerialize]
221 public ValueInput myValueA;
222
223 [DoNotSerialize]
224 public ValueInput myValueB;
225
226 [DoNotSerialize]
227 public ValueOutput result;
228
229 private string resultValue;
230
231 protected override void Definition()
232 {
233 ...
234 }
235}
236```
237
238The port's label is still visible in the Graph Inspector. Use the same name in a port's variable definition and the port's key in the `Definition` method for the node's class, as shown:
239
240```C#
241using System;
242using Unity.VisualScripting;
243using UnityEngine;
244
245public class MyNode : Unit
246{
247 ...
248
249 [DoNotSerialize, PortLabelHidden]
250 public ValueInput myValueA;
251
252 [DoNotSerialize, PortLabelHidden]
253 public ValueInput myValueB;
254
255 ...
256
257 protected override void Definition()
258 {
259 ...
260
261 myValueA = ValueInput<string>("myValueA", "Hello ");
262 myValueB = ValueInput<string>("myValueB", String.Empty);
263
264 ...
265 }
266}
267```