Skip to content

File layout and namespaces

SyntaxDescriptionNote
struct NsHelper { ... }Helper types in the same fileThe only thing that can’t share the file is a second concrete Behaviour.
namespace Sample { ... }Namespace declaration
namespace Sample.InnerNested namespaces
using V = UnityEngine.Vector3;Alias (using alias)
using static UnityEngine.Mathf;using for static members
UnityEngine.Debug.Log(...)Fully qualified name
public int V;Visible from anywhere
private int V;Visible only inside the declaring type
protected int V;The type itself and derived types
internal int V;Within the same program
protected internal int V;The same program, or a derived type
private protected int V;The same program, and a derived type
int a = 1;Hiding by an inner name
int V = 1;Hiding through nesting
for (int i = …) { }Scope of the for-loop variable
global::System.Int32.MaxValueAlias for the global namespace
nameof(value)Stringifying a parameter name
public static void Main()Writing MainA program’s entry points are the events the base declares.
SyntaxDescriptionErrorReasonAlternative
Two concrete Behaviours in one fileOne file is one programTUKI0109by designSplit the file
Both using Tsukimi; and using UdonSharp;A type with the same name is visible from two namespacesCS0104by designRemove one of the usings
Take(int v) and Take(ref int v)An overload that differs only in how the argument is passedTUKI0001not yetRename it (Variables and argument passing)
Two concrete Behaviours in one fileA TUKI0109 error (helper types can share the file)
Access modifierAll 6 can be written
LINQThe error isn’t about iterators or delegates but about the namespace being absent. The single line using System.Linq; produces CS0234, and the compiler says it can’t find System.Linq
MainIt can be written but is never called. Entry points are the events the base declares (Events), and the runtime calls those

struct, record, enum, interfaces, and static classes can share the same file.

using UnityEngine;
using Tsukimi;
public struct NsHelper
{
public int V;
}
public class NsWithHelper : TsukimiBehaviour
{
void Start()
{
NsHelper h = new NsHelper();
Debug.Log(h.V); // => 0
}
}
using UnityEngine;
using Tsukimi;
namespace Sample
{
public class NsBlock : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
}
}
using UnityEngine;
using Tsukimi;
namespace Sample.Inner
{
public class NsNested : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
}
}
using UnityEngine;
using Tsukimi;
using V = UnityEngine.Vector3;
public class NsAlias : TsukimiBehaviour
{
void Start()
{
V v = new V(1f, 2f, 3f);
Debug.Log(v); // => value from the runtime
}
}
using UnityEngine;
using Tsukimi;
using static UnityEngine.Mathf;
public class NsUsingStatic : TsukimiBehaviour
{
void Start()
{
Debug.Log(Abs(-1f)); // => 1
}
}
using Tsukimi;
public class NsQualified : TsukimiBehaviour
{
void Start()
{
UnityEngine.Debug.Log(UnityEngine.Mathf.Abs(-1f)); // => 1
}
}

A field marked public appears in the Inspector (Attributes).

using UnityEngine;
using Tsukimi;
public class BcPublic : TsukimiBehaviour
{
void Start()
{
Debug.Log(V); // => 0
}
public int V;
}
using UnityEngine;
using Tsukimi;
public class BcPrivate : TsukimiBehaviour
{
void Start()
{
Debug.Log(V); // => 0
}
private int V;
}
using UnityEngine;
using Tsukimi;
public class BcProtected : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
protected int V;
}
using UnityEngine;
using Tsukimi;
public class BcInternal : TsukimiBehaviour
{
void Start()
{
Debug.Log(V); // => 0
}
internal int V;
}
using UnityEngine;
using Tsukimi;
public class BcProtInt : TsukimiBehaviour
{
void Start()
{
Debug.Log(V); // => 0
}
protected internal int V;
}
using UnityEngine;
using Tsukimi;
public class BcPrivProt : TsukimiBehaviour
{
void Start()
{
Debug.Log(V); // => 0
}
private protected int V;
}
using UnityEngine;
using Tsukimi;
public class BcSimpleName : TsukimiBehaviour
{
void Start()
{
int a = 1;
Debug.Log(a); // => 1
}
private int a = 2;
}
using UnityEngine;
using Tsukimi;
public class BcHideNesting : TsukimiBehaviour
{
void Start()
{
int V = 1;
Debug.Log(V); // => 1
}
private int V = 2;
}
using UnityEngine;
using Tsukimi;
public class BcForScope : TsukimiBehaviour
{
void Start()
{
for (int i = 0; i < 2; i++) { Debug.Log(i); }
for (int i = 0; i < 2; i++) { Debug.Log(i); }
}
}
// Output
// 0
// 1
// 0
// 1
using UnityEngine;
using Tsukimi;
public class BcGlobalQual : TsukimiBehaviour
{
void Start()
{
Debug.Log(global::System.Int32.MaxValue); // => 2147483647
}
}
using UnityEngine;
using Tsukimi;
public class BcNameofParam : TsukimiBehaviour
{
void Start()
{
Debug.Log(Take(1)); // => "value"
}
private string Take(int value) { return nameof(value); }
}

Main can be written, but the runtime doesn’t call it.

using UnityEngine;
using Tsukimi;
public class BcMain : TsukimiBehaviour
{
void Start()
{
Debug.Log(1); // => 1
}
public static void Main() { }
}