# Fundamentals

Basic information that everyone should be aware of when developing with UdonSharp

# Access Modifiers

### <span style="color: #3598db;">What Are Access Modifiers?</span>

All types and type members in C# have an accessibility level and access modifiers are for controlling where they can be used from.

<table border="1" id="bkmrk-caller%27s-location-pu" style="border-collapse: collapse; width: 100%; height: 181.578px;"><tbody><tr style="height: 32.5938px;"><td style="width: 29.2954%; height: 32.5938px;">**Caller's location**

</td><td style="width: 8.65266%; height: 32.5938px;">**public**</td><td style="width: 16.9345%; height: 32.5938px;">**protected internal**</td><td style="width: 11.2485%; height: 32.5938px;">**protected**</td><td style="width: 9.2707%; height: 32.5938px;">**internal**</td><td style="width: 16.6877%; height: 32.5938px;">**private protected**</td><td style="width: 8.03415%; height: 32.5938px;">**private**</td></tr><tr style="height: 29.7969px;"><td style="width: 29.2954%; height: 29.7969px;">Within the class</td><td style="width: 8.65266%; height: 29.7969px;">✔️️</td><td style="width: 16.9345%; height: 29.7969px;">✔️️</td><td style="width: 11.2485%; height: 29.7969px;">✔️️</td><td style="width: 9.2707%; height: 29.7969px;">✔️️</td><td style="width: 16.6877%; height: 29.7969px;">✔️️</td><td style="width: 8.03415%; height: 29.7969px;">✔️️</td></tr><tr style="height: 29.7969px;"><td style="width: 29.2954%; height: 29.7969px;">Derived class (same assembly)</td><td style="width: 8.65266%; height: 29.7969px;">✔️️</td><td style="width: 16.9345%; height: 29.7969px;">✔️️</td><td style="width: 11.2485%; height: 29.7969px;">✔️️</td><td style="width: 9.2707%; height: 29.7969px;">✔️️</td><td style="width: 16.6877%; height: 29.7969px;">✔️️</td><td style="width: 8.03415%; height: 29.7969px;">❌</td></tr><tr style="height: 29.7969px;"><td style="width: 29.2954%; height: 29.7969px;">Non-derived class (same assembly)</td><td style="width: 8.65266%; height: 29.7969px;">✔️️</td><td style="width: 16.9345%; height: 29.7969px;">✔️️</td><td style="width: 11.2485%; height: 29.7969px;">❌</td><td style="width: 9.2707%; height: 29.7969px;">✔️️</td><td style="width: 16.6877%; height: 29.7969px;">❌</td><td style="width: 8.03415%; height: 29.7969px;">❌</td></tr><tr style="height: 29.7969px;"><td style="width: 29.2954%; height: 29.7969px;">Derived class (diff. assembly)</td><td style="width: 8.65266%; height: 29.7969px;">✔️️</td><td style="width: 16.9345%; height: 29.7969px;">✔️️</td><td style="width: 11.2485%; height: 29.7969px;">✔️️</td><td style="width: 9.2707%; height: 29.7969px;">❌</td><td style="width: 16.6877%; height: 29.7969px;">❌</td><td style="width: 8.03415%; height: 29.7969px;">❌</td></tr><tr style="height: 29.7969px;"><td style="width: 29.2954%; height: 29.7969px;">Non-derived class (diff. assembly)</td><td style="width: 8.65266%; height: 29.7969px;">✔️️</td><td style="width: 16.9345%; height: 29.7969px;">❌</td><td style="width: 11.2485%; height: 29.7969px;">❌</td><td style="width: 9.2707%; height: 29.7969px;">❌</td><td style="width: 16.6877%; height: 29.7969px;">❌</td><td style="width: 8.03415%; height: 29.7969px;">❌</td></tr></tbody></table>

<p class="callout info">[https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers)</p>

---

### <span style="color: #3598db;">What Access Modifiers Should I Use?</span>

UdonSharp 1.x supports all access modifiers for the source C# scripts to allow for better design of larger frameworks, so we can use them all just like we would with native C#.

<p class="callout success">Rule of thumb: Keep the access modifiers as strict as possible.</p>

---

### <span style="color: #3598db;">Common Mistakes</span>

Creators who may be new to C# development standards often expose everything in their classes by leaving fields and methods on ***public***, which in case of prefab distribution can lead to confusion.

<details id="bkmrk-example-1---fields-%7C"><summary>Example 1 - Fields \| Public vs Private + \[SerializeField\]</summary>

Simply setting the access modifier of a field to ***public*** is the easiest way of making it accessible in the Unity Editor, but it also exposes it in other scripts, which may be unwanted behavior.

We can change the access modifier of the field to ***private*** and add an attribute, ***\[SerializeField\]***. This will result in identical behavior on the inspector, but limits the scope of the field to that class only.

```C#
public bool publicField;

[SerializeField]
private bool privateSerializedField;
```

</details>

# Attributes

### <span style="color: rgb(53, 152, 219);">What are attributes?</span>

Attributes are ***"markers"*** or ***"tags"*** for associating metadata with code in a declarative way. They can be used to tell the Unity Editor, C# compiler, or even our own scripts how to treat certain ***classes***, ***fields***, ***methods***, and so on.

<p class="callout info">[https://docs.unity3d.com/Manual/Attributes.html](https://docs.unity3d.com/Manual/Attributes.html)</p>

Attributes are declared right before their target and are always wrapped in brackets:

```c#
using JetBrains.Annotations;
using System.Runtime.CompilerServices;
using UdonSharp;
using UnityEngine;
using UnityEngine.Serialization;
using Varneon.VUdon.Editors;
using Varneon.VUdon.Noclip.Abstract;
using Varneon.VUdon.Noclip.Enums;
using VRC.SDKBase;
using VRC.Udon.Common;

[assembly: InternalsVisibleTo("Varneon.VUdon.Noclip.Editor")]

namespace Varneon.VUdon.Noclip
{
    [SelectionBase]
    [DefaultExecutionOrder(-1000000000)]
    [AddComponentMenu("VUdon/Noclip")]
    [DisallowMultipleComponent]
    [HelpURL("https://github.com/Varneon/VUdon-Noclip/wiki/Settings")]
    [UdonBehaviourSyncMode(BehaviourSyncMode.None)]
    public partial class Noclip : UdonSharpBehaviour
    {
        [FoldoutHeader("Options", "Options that can be edited before build and in-game")]
        [SerializeField]
        [Tooltip("Method for triggering the noclip mode")]
        private NoclipTriggerMethod noclipTriggerMethod = NoclipTriggerMethod.DoubleJump;

        [SerializeField]
        [FieldLabel("Toggle Threshold (s)")]
        [Tooltip("Time in which jump has to be double tapped in order to toggle noclip")]
        [FieldRange(0.1f, 1f)]
        private float toggleThreshold = 0.25f;

        [SerializeField]
        [FieldLabel("Speed (m/s)")]
        [Tooltip("Maximum speed in m/s")]
        [Min(1f)]
        [FormerlySerializedAs("velocity")]
        private float speed = 15f;

        [PublicAPI("Sets noclip enabled")]
        public void _SetNoclipEnabled(bool enabled)
        {
            SetNoclipEnabled(enabled);
        }

#if UNITY_EDITOR && !COMPILER_UDONSHARP
        [UsedImplicitly]
        [UnityEditor.Callbacks.PostProcessScene(-1)]
        private static void InitializeOnBuild() { }
#endif
    }
}
```

---

### <span style="color: rgb(53, 152, 219);">What attributes should I know about?</span>  


There are several quality of life attributes that everyone should know and use, and here are most of them:

#### <span style="color: rgb(53, 152, 219);">Field Attributes</span>

These attributes can be used on fields, primarily to alter their appearance in the inspector.

<table border="1" cellpadding="0" cellspacing="0" dir="ltr" id="bkmrk-%5Brange%5D-restrict-a-f" style="width: 80.4938%; height: 357.563px;"><colgroup><col style="width: 25.8065%;" width="245"></col><col style="width: 74.1935%;" width="437"></col></colgroup><tbody><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[Range]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">Range</span>\]](https://docs.unity3d.com/ScriptReference/RangeAttribute.html "https://docs.unity3d.com/ScriptReference/RangeAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Restrict a float or int variable to a specific range&quot;}" style="height: 29.7969px;">Restrict a float or int variable to a specific range</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[Min]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">Min</span>\]](https://docs.unity3d.com/ScriptReference/MinAttribute.html "https://docs.unity3d.com/ScriptReference/MinAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Restrict a float or int variable to a specific minimum value&quot;}" style="height: 29.7969px;">Restrict a float or int variable to a specific minimum value</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[Header]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">Header</span>\]](https://docs.unity3d.com/ScriptReference/HeaderAttribute.html "https://docs.unity3d.com/ScriptReference/HeaderAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Add a space and a header above a field in inspector&quot;}" style="height: 29.7969px;">Add a space and a header above a field in inspector</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[TextArea]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">TextArea</span>\]](https://docs.unity3d.com/ScriptReference/TextAreaAttribute.html "https://docs.unity3d.com/ScriptReference/TextAreaAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Make string field height-flexible and scrollable&quot;}" style="height: 29.7969px;">Make string field height-flexible and scrollable</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[ColorUsage]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">ColorUsage</span>\]](https://docs.unity3d.com/ScriptReference/ColorUsageAttribute.html "https://docs.unity3d.com/ScriptReference/ColorUsageAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Configure color field to support HDR and/or alpha&quot;}" style="height: 29.7969px;">Configure Color field to support HDR and/or alpha</td></tr><tr><td>[\[<span style="color: rgb(22, 145, 121);">GradientUsage</span>\]](https://docs.unity3d.com/ScriptReference/GradientUsageAttribute.html "https://docs.unity3d.com/ScriptReference/GradientUsageAttribute.html")</td><td>Configure Gradient field's color space and HDR</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[Space]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">Space</span>\]](https://docs.unity3d.com/ScriptReference/SpaceAttribute.html "https://docs.unity3d.com/ScriptReference/SpaceAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Add a space above a field in inspector&quot;}" style="height: 29.7969px;">Add a space above a field in inspector</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[SerializeField]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">SerializeField</span>\]](https://docs.unity3d.com/ScriptReference/SerializeField.html "https://docs.unity3d.com/ScriptReference/SerializeField.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Force Unity to serialize a private field&quot;}" style="height: 29.7969px;">Force Unity to serialize a private field</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[HideInInspector]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">HideInInspector</span>\]](https://docs.unity3d.com/ScriptReference/HideInInspector.html "https://docs.unity3d.com/ScriptReference/HideInInspector.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Hide a variable from the inspector&quot;}" style="height: 29.7969px;">Hide a variable from the inspector</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[Tooltip]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">Tooltip</span>\]](https://docs.unity3d.com/ScriptReference/TooltipAttribute.html "https://docs.unity3d.com/ScriptReference/TooltipAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Display a text in inspector when hovering over a field&quot;}" style="height: 29.7969px;">Display a text in inspector when hovering over a field</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[NonSerialized]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">NonSerialized</span>\]](https://docs.unity3d.com/ScriptReference/NonSerialized.html "https://docs.unity3d.com/ScriptReference/NonSerialized.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Prevent variable from being serialized (also hides from inspector)&quot;}" style="height: 29.7969px;">Prevent variable from being serialized (also hides from inspector)</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[NonReorderable]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">NonReorderable</span>\]](https://docs.unity3d.com/ScriptReference/NonReorderableAttribute.html "https://docs.unity3d.com/ScriptReference/NonReorderableAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Disable default reorderability in new array and list fields (Unity 2020.2+)&quot;}" style="height: 29.7969px;">Disable default reorderability in new array and list fields ***(<span style="color: rgb(35, 111, 161);">Unity 2020.2+</span>)***</td></tr><tr style="height: 29.7969px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[FormerlySerializedAs]&quot;}" style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">FormerlySerializedAs</span>\]](https://docs.unity3d.com/ScriptReference/Serialization.FormerlySerializedAsAttribute.html "https://docs.unity3d.com/ScriptReference/Serialization.FormerlySerializedAsAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Preserve original serialized value of a field when renaming it&quot;}" style="height: 29.7969px;">Preserve original serialized value of a field when renaming it</td></tr></tbody></table>

#### <span style="color: rgb(53, 152, 219);">Class Attributes</span>

These attributes can be used on classes.

<table border="1" cellpadding="0" cellspacing="0" dir="ltr" id="bkmrk-%5Budonbehavioursyncmo" style="width: 95.1852%; height: 247.734px;"><colgroup><col style="width: 27.5315%;" width="245"></col><col style="width: 72.4685%;" width="528"></col></colgroup><tbody><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[UdonBehaviourSyncMode]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">UdonBehaviourSyncMode</span>\]](https://udonsharp.docs.vrchat.com/udonsharp#udonbehavioursyncmode "https://udonsharp.docs.vrchat.com/udonsharp#udonbehavioursyncmode")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Enforce a synchronization mode of an UdonSharpBehaviour&quot;}" style="height: 35.3906px;">Enforce a synchronization mode of an UdonSharpBehaviour</td></tr><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[DefaultExecutionOrder]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">DefaultExecutionOrder</span>\]](https://udonsharp.docs.vrchat.com/udonsharp#defaultexecutionorder "https://udonsharp.docs.vrchat.com/udonsharp#defaultexecutionorder")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Specify the execution order of update loops in relation to other UdonSharpBehaviours&quot;}" style="height: 35.3906px;">Specify the execution order of update loops in relation to other UdonSharpBehaviours</td></tr><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[RequireComponent]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">RequireComponent</span>\]](https://docs.unity3d.com/ScriptReference/RequireComponent.html "https://docs.unity3d.com/ScriptReference/RequireComponent.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Add components automatically to the same object&quot;}" style="height: 35.3906px;">Add a component automatically to the same object and prevent its removal</td></tr><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[DisallowMultipleComponent]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">DisallowMultipleComponent</span>\]](https://docs.unity3d.com/ScriptReference/DisallowMultipleComponent.html "https://docs.unity3d.com/ScriptReference/DisallowMultipleComponent.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Prevent multiple instances of the component from being added to the same object&quot;}" style="height: 35.3906px;">Prevent multiple instances of the component from being added to the same object</td></tr><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[AddComponent]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">AddComponent</span>\]](https://docs.unity3d.com/ScriptReference/AddComponentMenu.html "https://docs.unity3d.com/ScriptReference/AddComponentMenu.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Specify the path to this component in the \&quot;Add Component\&quot; menu&quot;}" style="height: 35.3906px;">Specify the path to this component in the "Add Component" menu</td></tr><tr style="height: 35.3906px;"><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;[ExcludeFromPreset]&quot;}" style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">ExcludeFromPreset</span>\]](https://docs.unity3d.com/ScriptReference/ExcludeFromPresetAttribute.html "https://docs.unity3d.com/ScriptReference/ExcludeFromPresetAttribute.html")</td><td data-sheets-value="{&quot;1&quot;:2,&quot;2&quot;:&quot;Prevent creation of presets from instances of the class&quot;}" style="height: 35.3906px;">Prevent creation of presets from instances of the class</td></tr><tr style="height: 35.3906px;"><td style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">SelectionBase</span>\]](https://docs.unity3d.com/ScriptReference/SelectionBaseAttribute.html "https://docs.unity3d.com/ScriptReference/SelectionBaseAttribute.html")</td><td style="height: 35.3906px;">Mark the GameObject as a selection base object for Scene View picking</td></tr><tr><td>[\[<span style="color: rgb(22, 145, 121);">Icon</span>\]](https://docs.unity3d.com/ScriptReference/IconAttribute.html "https://docs.unity3d.com/ScriptReference/IconAttribute.html")</td><td>Specify an icon for a MonoBehaviour or ScriptableObject ***(<span style="color: rgb(35, 111, 161);">Unity 2021.3+</span>)***</td></tr></tbody></table>

#### <span style="color: rgb(53, 152, 219);">Method Attributes</span>

These attributes can be used on methods.

<table border="1" id="bkmrk-%5Bcontextmenu%5D-add-a-" style="border-collapse: collapse; width: 60.9877%; height: 29.7969px;"><colgroup><col style="width: 29.0875%;"></col><col style="width: 70.9125%;"></col></colgroup><tbody><tr style="height: 29.7969px;"><td style="height: 29.7969px;">[\[<span style="color: rgb(22, 145, 121);">ContextMenu</span>\]](https://docs.unity3d.com/ScriptReference/ContextMenu.html "https://docs.unity3d.com/ScriptReference/ContextMenu.html")</td><td style="height: 29.7969px;">Add a command to the Component's context menu</td></tr></tbody></table>

#### <span style="color: rgb(53, 152, 219);">Common Attributes</span>

<table border="1" id="bkmrk-%5Bobsolete%5D-mark-an-e" style="border-collapse: collapse; width: 87.4074%; height: 106.172px;"><colgroup><col style="width: 20.4451%;"></col><col style="width: 79.5549%;"></col></colgroup><tbody><tr style="height: 35.3906px;"><td style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">Obsolete</span>\]](https://learn.microsoft.com/en-us/dotnet/api/system.obsoleteattribute?view=net-7.0 "https://learn.microsoft.com/en-us/dotnet/api/system.obsoleteattribute?view=net-7.0")</td><td style="height: 35.3906px;">Mark an element to be no longer in use</td></tr><tr style="height: 35.3906px;"><td style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">PublicAPI</span>\]](https://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html#PublicAPIAttribute "https://www.jetbrains.com/help/resharper/Reference&#95;&#95;Code&#95;Annotation&#95;Attributes.html#PublicAPIAttribute")</td><td style="height: 35.3906px;">Mark publicly available API which should not be removed and treated as used</td></tr><tr style="height: 35.3906px;"><td style="height: 35.3906px;">[\[<span style="color: rgb(22, 145, 121);">UsedImplicitly</span>\]](https://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html#UsedImplicitlyAttribute "https://www.jetbrains.com/help/resharper/Reference&#95;&#95;Code&#95;Annotation&#95;Attributes.html#UsedImplicitlyAttribute")</td><td style="height: 35.3906px;">Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library)</td></tr><tr><td>[\[<span style="color: rgb(22, 145, 121);">NotNull</span>\]](https://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html#NotNullAttribute "https://www.jetbrains.com/help/resharper/Reference&#95;&#95;Code&#95;Annotation&#95;Attributes.html#NotNullAttribute")</td><td>Indicates that the value of the marked element can never be null</td></tr><tr><td>[\[<span style="color: rgb(22, 145, 121);">CanBeNull</span>\]](https://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html#CanBeNullAttribute "https://www.jetbrains.com/help/resharper/Reference&#95;&#95;Code&#95;Annotation&#95;Attributes.html#CanBeNullAttribute")</td><td>Indicates that the value of the marked element could be null sometimes</td></tr></tbody></table>

#### <span style="color: rgb(53, 152, 219);">Other Attributes</span>

These attributes don't fall into the categories above, but are extremely useful and commonly used.

---

##### [\[<span style="color: rgb(22, 145, 121);">InternalsVisibleTo</span>\]](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute?view=net-7.0 "https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute?view=net-7.0")

This attribute allows you to make your Runtime assembly's [internal](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal "https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal") members visible to the Editor assembly.

<p class="callout info">Example of this attribute being used: [Udonity's AssemblyInfo.cs](https://github.com/Varneon/VUdon-Udonity/blob/main/Packages/com.varneon.vudon.udonity/Runtime/AssemblyInfo.cs "https://github.com/Varneon/VUdon-Udonity/blob/main/Packages/com.varneon.vudon.udonity/Runtime/AssemblyInfo.cs")</p>

1. Create a new C# file called &#96;AssemblyInfo.cs&#96; into your Runtime folder
2. Add the following content inside the file:  
    
    ```c#
    using System.Runtime.CompilerServices;
    [assembly: InternalsVisibleTo("YOUR_EDITOR_ASSEMBLY_NAME_HERE")]
    ```

---

##### [\[<span style="color: rgb(22, 145, 121);">CreateAssetMenu</span>\]](https://docs.unity3d.com/ScriptReference/CreateAssetMenuAttribute.html "https://docs.unity3d.com/ScriptReference/CreateAssetMenuAttribute.html")

Mark a [ScriptableObject](https://docs.unity3d.com/ScriptReference/ScriptableObject.html "https://docs.unity3d.com/ScriptReference/ScriptableObject.html")-derived type to be automatically listed in the Assets/Create submenu.

Learn more about ScriptableObjects [here](https://vrclibrary.com/wiki/books/varneons-unity-development-handbook/page/scriptable-objects "https://vrclibrary.com/wiki/books/varneons-unity-development-handbook/page/scriptable-objects").

```c#
// menuName: Path to the menu item
// fileName: Default name of the new file
// order: Priority of the menu item (100 is often reasonble)
[CreateAssetMenu(menuName = "VUdon - Vehicles/Data Presets/Car Spec Sheet", fileName = "NewCarSpecSheet.asset", order = 100)]
public class CarSpecSheet : ScriptableObject { }
```

---

##### [\[<span style="color: rgb(22, 145, 121);">InspectorName</span>\]](https://docs.unity3d.com/ScriptReference/InspectorNameAttribute.html "https://docs.unity3d.com/ScriptReference/InspectorNameAttribute.html")

Use this attribute on enum value declarations to change the display name shown in the Inspector.

```c#
public enum ColorDisplayMode
{
    [InspectorName("RGB 0-255")]
    RGB255,

    [InspectorName("RGB 0-1.0")]
    RGB1,

    HSV
}
```

# Namespaces

### <span style="color: #3598db;">What are namespaces?</span>

<p class="callout info">Namespaces are a fundamental feature in C# and are used to control the scope of your projects.</p>

<p class="callout success">When developing anything with UdonSharp, declaring your own namespaces should be one of the first steps of your development process.</p>

<p class="callout warning">If a creator doesn't declare their own namespace for their UdonSharpBehaviours, all of their classes will be exposed to the entire project by default and may cause misunderstandings and confusion, especially amongst beginners.</p>

<p class="callout info">[https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/namespaces](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/namespaces)</p>

---

### <span style="color: #3598db;">How to declare a namespace in UdonSharp?</span>

In order to declare your own namespace for a project, all you have to do is encapsulate your class in curly brackets, lead by the ***namespace*** keyword and your desired namespace.

```C#
namespace Varneon.ExamplePrefab
{
	public class ExampleClass : UdonSharpBehaviour
    {
    
    }
}
```

<p class="callout success">It is highly recommended to always have the first element of the namespace be your own name (or brand, if you have one).</p>

<p class="callout warning">DO NOT use anyone else's name for the namespace unless you are working on the project for them!</p>

---

### <span style="color: #3598db;">How to access classes in other namespace?</span>

In order to access classes in other namespaces, all you have to do is use the ***using*** keyword to extend the scope of your project to that other namespace

```C#
using Varneon.ExamplePrefab;

namespace Varneon.OtherExamplePrefab
{
	public class OtherExampleClass : UdonSharpBehaviour
    {
    	private ExampleClass exampleClass;
    }
}
```

<p class="callout info">Usage of namespaces makes it clear who is the developer of the project and makes it often easier to find specific project's scope [![image-1659620217781.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1659620217781.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1659620217781.png)</p>

---

### <span style="color: #3598db;">TLDR - Why use namespaces?</span>

- **Define clear scope for your project**
- **Prevent classes and enums from leaking to the default project scope**

# Assembly Definitions

<p class="callout warning">Assembly Definitions can be overwhelming for beginners, but should be essential knowledge for developers of widely used prefabs made with UdonSharp.</p>

<p class="callout info">I have just released a new Unity Editor extension for automating assembly definition generation: [Experimental Automatic Assembly Definition Generator by Varneon \| GitHub](https://github.com/Varneon/AssemblyDefinitionGenerator "https://github.com/Varneon/AssemblyDefinitionGenerator")</p>

### <span style="color: #3598db;">What are assembly definitions?</span>

<p class="callout info">Assembly Definitions and Assembly References are assets that you can create to organize your <span class="tooltip">scripts </span>into assemblies.</p>

<p class="callout info">[https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html)</p>

---

### <span style="color: #3598db;">Why use assembly definitions?</span>

<p class="callout success">Usage of assembly definitions promotes modularity and assists with declaring a clear scope for the dependencies</p>

<p class="callout success">Assembly definitions support Define Constraints: only compile the assembly if specific Scripting Define Symbol is present (e.g. if you only want the assembly to compile if the symbol "UDONSHARP" is present, you can add it as a constraint)</p>

---

### <span style="color: #3598db;">How to use assembly definitions with U# 1.x?</span>

<p class="callout info">U# requires a custom U# Assembly Definition to be present alongside with the main Assembly Definition when U# scripts are in said assembly</p>

<details id="bkmrk-1%29-create-assembly-d"><summary>1) Create Assembly Definition</summary>

[![image-1661019953736.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661019953736.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661019953736.png)

<p class="callout info">Name the Assembly Definition file clearly to indicate the developer and the project (Recommended to use similar format to namespaces)</p>

[![image-1661020045130.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661020045130.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661020045130.png)

<p class="callout info">Right after creating the assembly, you may notice errors appearing in your console, this is because the assemblies of the scripts that our scripts are referencing, aren't defined in the assembly definition</p>

[![image-1661020225203.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661020225203.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661020225203.png)

</details><details id="bkmrk-2%29-define-the-assemb"><summary>2) Define the assembly references</summary>

<p class="callout success">Adding **UdonSharp.Runtime** assembly as a reference allows us to reference the scripts contained in that assembly from our own scripts</p>

<p class="callout info">If you need to access common VRChat's classes, such as VRCPickup or UdonBehaviour, other common assemblies to reference are **VRC.Udon** and **VRC.SDK3**</p>

<p class="callout warning">**Disabling the option "Use GUIDs" is recommended, since the GUIDs may change over time** </p>

[![image-1661020467667.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661020467667.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661020467667.png)

<p class="callout info">Right after clicking "Apply" on the assembly definition the scripts will attempt to compile, and you will most likely see the following error in the console. We will fix this next.</p>

[![image-1661021023795.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661021023795.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661021023795.png)

</details><details id="bkmrk-3%29-create-u%23-assembl"><summary>3) Create U# Assembly Definition</summary>

[![image-1661021108017.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661021108017.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661021108017.png)

<p class="callout danger">Make sure to name the U# Assembly Definition file identically to the main assembly definition's name!</p>

[![image-1661021161988.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661021161988.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661021161988.png)

<p class="callout info">As the last step, assign the main assembly definition as the "Source Assembly" on the U# assembly definition</p>

[![image-1661021296415.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661021296415.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661021296415.png)

<p class="callout success">Now all of your UdonSharpBehaviours should compile successfully and you can continue the development</p>

<p class="callout info">If UdonSharp still throws an error related to the scripts not being a part of a U# assembly, try reimporting the U# assets and scripts in the folder.</p>

[![image-1661021928118.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/scaled-1680-/image-1661021928118.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-08/image-1661021928118.png)

</details>