Skip to content

The shape of a program

SyntaxDescription
struct NsHelper { ... }Helper types in the same file
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 Main
SyntaxDescriptionErrorReasonInstead
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)
Putting two concrete Behaviours in one file stops with TUKI0109. Helper types can share the file.

All six access modifiers can be written.

Main compiles but isn’t called. The entry point is an event the base class declares (Events), and the runtime calls that.

struct / record / enum / interfaces / static classes can share the same file. Only a second concrete Behaviour can’t.

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)); // => value from the runtime
}
}
using Tsukimi;
public class NsQualified : TsukimiBehaviour
{
void Start()
{
UnityEngine.Debug.Log(UnityEngine.Mathf.Abs(-1f)); // => value from the runtime
}
}

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 compiles, but the runtime doesn’t call it. The program’s entry point is an event the base class declares.

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