Arrays
An array holds a fixed number of values of the same type, decided in advance. The length can’t change afterward.
List and Dictionary aren’t available, so arrays hold multiple values together.
Forms that compile (48)
Section titled “Forms that compile (48)”Forms that don’t compile (19)
Section titled “Forms that don’t compile (19)”| Syntax | Description | Error | Reason |
|---|---|---|---|
int[,,] a = new int[2, 2, 2]; | Multidimensional arrays with 3 or more dimensions | TUKI0001 | not yet |
new int[2, 2] { { 1, 2 }, { 3, 4 } } | Listed initial values for a 2D array | TUKI0001 | undecided |
foreach (int v in grid) | Iterating a 2D array | TUKI0001 | by design |
Swap(ref a) | Passing to your own method with ref | TUKI0001 | runtime |
Make(out int[] b) | Receiving from your own method with out | TUKI0001 | runtime |
Bump(ref a[0]) | Passing an element with ref | TUKI0001 | runtime |
boxed is Vector3[] | Type test for whether something is an array type | TUKI0001 | not yet |
System.Array.IndexOf(a, 1) | Finding an element | TUKI0001 | not yet |
System.Array.Reverse(a) | Reversing the order | TUKI0001 | not yet |
System.Array.Sort(a) | Sorting | TUKI0001 | not yet |
System.Array.Resize(ref a, 5) | Changing the length | TUKI0001 | undecided |
new List<int>() | List (variable-length sequence) | TUKI0102, TUKI0101 | runtime |
new Dictionary<int, int>() | Dictionary | TUKI0102, TUKI0101 | runtime |
using System.Linq; | LINQ query expressions | CS0234 (the namespace itself doesn’t exist) | runtime |
foreach (int v in list) | Iterating something other than an array | TUKI0001, TUKI0101, TUKI0102 | runtime |
s[^1] | Index from the end of a string | TUKI0001 | not yet |
points[1..] | Slicing an array of structs | TUKI0001 | not yet |
System.Index i = 0; | A type that represents a position | TUKI0102, TUKI0101, TUKI0099 | runtime |
System.Range r = 0..1; | A type that represents a range | TUKI0102, TUKI0099 | runtime |
Forms to use instead
Section titled “Forms to use instead”| Form you want to use | Alternative |
|---|---|
| List | An array sized larger than needed, plus a variable for how many are in use |
| Dictionary | If the key is a small integer or an enum, an array indexed by the key. Otherwise, hold a key array and a value array as a pair and search through them in order. |
| Arrays with 3 or more dimensions | A jagged array (int[2][][]), or a single array using z * w * h + y * w + x |
| Iterating a 2D array | A nested for using GetLength(0) and GetLength(1) |
Rewriting with ref/out | Pass the array and rewrite its contents, or return it as a return value |
Declaration and generation
Section titled “Declaration and generation”Generation with a fixed length
Section titled “Generation with a fixed length”using UnityEngine;using Tsukimi;
public class ArraysDeclareFixedLength : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[4]; }}Generation with the length from a variable
Section titled “Generation with the length from a variable”using UnityEngine;using Tsukimi;
public class ArraysDeclareVariableLength : TsukimiBehaviour{ public int count = 4;
private int[] scores;
void Start() { scores = new int[count]; scores[0] = 10; }}Generation with listed initial values
Section titled “Generation with listed initial values”using UnityEngine;using Tsukimi;
public class ArraysDeclareInitializer : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[] { 1, 2, 3 }; }}Initialization at declaration
Section titled “Initialization at declaration”You can omit new int[] when writing it at the same time as the declaration.
using UnityEngine;using Tsukimi;
public class ArraysDeclareShortInitializer : TsukimiBehaviour{ private int[] scores = { 1, 2, 3 };
void Start() { scores[0] = 10; }}Inferring the element type
Section titled “Inferring the element type”using UnityEngine;using Tsukimi;
public class ArraysDeclareInferredInitializer : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new[] { 1, 2, 3 }; }}Inferring the variable’s type
Section titled “Inferring the variable’s type”using UnityEngine;using Tsukimi;
public class ArraysDeclareVar : TsukimiBehaviour{ private int[] scores;
void Start() { var made = new int[4]; made[0] = 10; scores = made; }}Generating a jagged array
Section titled “Generating a jagged array”using UnityEngine;using Tsukimi;
public class ArraysDeclareJagged : TsukimiBehaviour{ private int[][] grid;
void Start() { grid = new int[4][]; Debug.Log(grid[0] == null); // => true grid[0] = new int[4]; grid[0][0] = 1; Debug.Log(grid[0][0]); // => 1 }}Initializing a jagged array
Section titled “Initializing a jagged array”using UnityEngine;using Tsukimi;
public class ArraysDeclareJaggedInitializer : TsukimiBehaviour{ private int[][] grid;
void Start() { grid = new int[][] { new int[] { 1, 2 }, new int[] { 3 } }; grid[0][0] = 10; }}3 levels of nesting
Section titled “3 levels of nesting”using UnityEngine;using Tsukimi;
public class ArraysDeclareJaggedThreeLevels : TsukimiBehaviour{ private int[][][] deep;
void Start() { deep = new int[2][][]; deep[0] = new int[2][]; deep[0][0] = new int[2]; deep[0][0][0] = 1; }}4 levels of nesting
Section titled “4 levels of nesting”There’s no limit to the number of levels.
using UnityEngine;using Tsukimi;
public class ArraysDeclareJaggedFourLevels : TsukimiBehaviour{ private int[][][][] deep;
void Start() { deep = new int[2][][][]; deep[0] = new int[2][][]; deep[0][0] = new int[2][]; deep[0][0][0] = new int[2]; deep[0][0][0][0] = 1; Debug.Log(deep[0][0][0][0]); // => 1 }}Generating a 2D array
Section titled “Generating a 2D array”There are at most 2 dimensions. Elements go into and out of a box one at a time, so it takes more instructions than a same-sized 1D array or jagged array.
using UnityEngine;using Tsukimi;
public class ArraysMultidimensional : TsukimiBehaviour{ void Start() { int[,] grid = new int[4, 4]; grid[0, 0] = 1; Debug.Log(grid[0, 0]); // => 1 Debug.Log(grid.GetLength(1)); // => 4 }}Element is a reference type
Section titled “Element is a reference type”using UnityEngine;using Tsukimi;
public class ArraysElementReferenceType : TsukimiBehaviour{ private string[] names;
void Start() { names = new string[4]; Debug.Log(names[0] == null); // => true names[0] = "hello"; Debug.Log(names[0]); // => "hello" }}Element is a struct
Section titled “Element is a struct”using UnityEngine;using Tsukimi;
public class ArraysElementStructType : TsukimiBehaviour{ void Start() { Vector3[] points = new Vector3[4]; points[0] = new Vector3(1f, 2f, 3f); }}Element is a runtime type
Section titled “Element is a runtime type”Types the runtime exposes can also be elements.
using UnityEngine;using Tsukimi;
public class ArraysElementObjectType : TsukimiBehaviour{ void Start() { GameObject[] targets = new GameObject[4]; targets[0] = gameObject; }}Element access
Section titled “Element access”Writing to an element
Section titled “Writing to an element”using UnityEngine;using Tsukimi;
public class ArraysWriteElement : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[4]; scores[0] = 10; }}Reading an element
Section titled “Reading an element”using UnityEngine;using Tsukimi;
public class ArraysReadElement : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; int first = scores[0]; Debug.Log(first); // => 1 }}Compound assignment
Section titled “Compound assignment”using UnityEngine;using Tsukimi;
public class ArraysCompoundAssign : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[4]; scores[0] += 10; }}Increment and decrement
Section titled “Increment and decrement”using UnityEngine;using Tsukimi;
public class ArraysIncrementElement : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[4]; scores[0]++; }}Specifying the index with a variable
Section titled “Specifying the index with a variable”using UnityEngine;using Tsukimi;
public class ArraysIndexByVariable : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[] { 1, 2, 3 }; int i = 1; scores[i] = 10; }}Index from the end
Section titled “Index from the end”^1 is the last element. It points to the same position as a[a.Length - 1].
using UnityEngine;using Tsukimi;
public class ArraysIndexFromEnd : TsukimiBehaviour{ void Start() { int[] a = { 1, 2, 3 }; Debug.Log(a[^1]); // => 3 }}Slicing a range
Section titled “Slicing a range”A new array is created, and the elements in the given range are copied into it. The original array doesn’t change.
using UnityEngine;using Tsukimi;
public class ArraysRangeSlice : TsukimiBehaviour{ void Start() { int[] a = { 1, 2, 3 }; int[] b = a[1..]; Debug.Log(b.Length); // => 2 Debug.Log(b[0]); // => 2 }}Writing to a field of a struct element
Section titled “Writing to a field of a struct element”using UnityEngine;using Tsukimi;
public class ArraysStructElementFieldWrite : TsukimiBehaviour{ void Start() { Vector3[] points = new Vector3[4]; points[0].x = 5f; }}Retrieving a struct element
Section titled “Retrieving a struct element”What goes into the variable is a copy, so changing that variable doesn’t change the array’s element.
using UnityEngine;using Tsukimi;
public class ArraysCopyStructElement : TsukimiBehaviour{ void Start() { Vector3[] points = new Vector3[4]; Vector3 copy = points[0]; copy.y = 9f; Debug.Log(copy); // => runtime value }}Members
Section titled “Members”Getting the element count
Section titled “Getting the element count”using UnityEngine;using Tsukimi;
public class ArraysLength : TsukimiBehaviour{ void Start() { int[] scores = new int[4]; int n = scores.Length; Debug.Log(n); // => 4 }}Getting the rank
Section titled “Getting the rank”using UnityEngine;using Tsukimi;
public class ArraysRank : TsukimiBehaviour{ void Start() { int[] scores = new int[4]; int r = scores.Rank; Debug.Log(r); // => 1 }}Getting the length of a given dimension
Section titled “Getting the length of a given dimension”using UnityEngine;using Tsukimi;
public class ArraysGetLength : TsukimiBehaviour{ void Start() { int[] scores = new int[4]; int n = scores.GetLength(0); Debug.Log(n); // => 4 }}Reading regardless of type
Section titled “Reading regardless of type”The return value is object, so you need to convert it before use.
using UnityEngine;using Tsukimi;
public class ArraysGetValue : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; object first = scores.GetValue(0); Debug.Log(first); // => 1 }}Writing regardless of type
Section titled “Writing regardless of type”using UnityEngine;using Tsukimi;
public class ArraysSetValue : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[3]; scores.SetValue(9, 0); }}Cloning
Section titled “Cloning”The return value is object, so you need to convert it before use.
using UnityEngine;using Tsukimi;
public class ArraysClone : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; object copy = scores.Clone(); Debug.Log(copy); // => System.Object[] }}Copying to another array
Section titled “Copying to another array”using UnityEngine;using Tsukimi;
public class ArraysArrayCopy : TsukimiBehaviour{ private int[] destination;
void Start() { int[] source = new int[] { 1, 2, 3 }; destination = new int[3]; System.Array.Copy(source, destination, 3); }}Clearing a range
Section titled “Clearing a range”using UnityEngine;using Tsukimi;
public class ArraysArrayClear : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; System.Array.Clear(scores, 0, 3); }}Iteration
Section titled “Iteration”Iterating all elements
Section titled “Iterating all elements”using UnityEngine;using Tsukimi;
public class ArraysForeach : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; int sum = 0; foreach (int v in scores) { sum += v; } Debug.Log(sum); // => 6 }}Iteration with the type inferred
Section titled “Iteration with the type inferred”using UnityEngine;using Tsukimi;
public class ArraysForeachVar : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; int sum = 0; foreach (var v in scores) { sum += v; } Debug.Log(sum); // => 6 }}Iteration by index
Section titled “Iteration by index”using UnityEngine;using Tsukimi;
public class ArraysForIndex : TsukimiBehaviour{ void Start() { int[] scores = new int[] { 1, 2, 3 }; int sum = 0; for (int i = 0; i < scores.Length; i++) { sum += scores[i]; } Debug.Log(sum); // => 6 }}Storage
Section titled “Storage”Holding as a field
Section titled “Holding as a field”using UnityEngine;using Tsukimi;
public class ArraysFieldPrivate : TsukimiBehaviour{ private int[] buffer;
void Start() { buffer = new int[16]; buffer[0] = 10; }}Assigning via a public field
Section titled “Assigning via a public field”A public field appears in the inspector, and you can set its value there.
using UnityEngine;using Tsukimi;
public class ArraysFieldPublic : TsukimiBehaviour{ public GameObject[] targets;
void Start() { targets[0] = gameObject; }}If you don’t specify a sync method, it uses the default method.
using UnityEngine;using Tsukimi;
public class ArraysFieldSynced : TsukimiBehaviour{ [UdonSynced] private int[] values = new int[4];
void Start() { values[0] = 10; RequestSerialization(); }}Passing as an argument
Section titled “Passing as an argument”using UnityEngine;using Tsukimi;
public class ArraysPassAsArgument : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[] { 1, 2, 3 }; Fill(scores); }
private void Fill(int[] target) { target[0] = 10; }}Receiving as a variable number of arguments
Section titled “Receiving as a variable number of arguments”using UnityEngine;using Tsukimi;
public class ArraysParamsParameter : TsukimiBehaviour{ void Start() { int total = Total(1, 2, 3); Debug.Log(total); // => 6 }
private int Total(params int[] values) { int sum = 0; for (int i = 0; i < values.Length; i++) { sum += values[i]; } return sum; }}Returning as a return value
Section titled “Returning as a return value”using UnityEngine;using Tsukimi;
public class ArraysReturnFromMethod : TsukimiBehaviour{ private int[] scores;
void Start() { scores = Make(); scores[0] = 10; }
private int[] Make() { return new int[4]; }}Assigning to another variable
Section titled “Assigning to another variable”using UnityEngine;using Tsukimi;
public class ArraysAliasSharesReference : TsukimiBehaviour{ void Start() { int[] original = new int[4]; int[] alias = original; alias[0] = 10; Debug.Log(original[0]); // => 10 }}Comparing with null
Section titled “Comparing with null”using UnityEngine;using Tsukimi;
public class ArraysCompareToNull : TsukimiBehaviour{ private int[] buffer;
void Start() { Debug.Log(buffer == null); // => true if (buffer == null) { buffer = new int[4]; } Debug.Log(buffer.Length); // => 4 }}Storing in object
Section titled “Storing in object”An array is a reference, so it goes into an object variable as is.
using UnityEngine;using Tsukimi;
public class ArraysStoreInObject : TsukimiBehaviour{ void Start() { int[] scores = new int[4]; object boxed = scores; Debug.Log(boxed); // => System.Object[] }}Assigning to an array with a wider element type
Section titled “Assigning to an array with a wider element type”string[] can be treated as object[]. This only works in the direction that widens the element type.
using UnityEngine;using Tsukimi;
public class ArraysCovariantAssign : TsukimiBehaviour{ void Start() { string[] names = new string[4]; object[] boxes = names; Debug.Log(boxes.Length); // => 4 }}Storing in an element of an object array
Section titled “Storing in an element of an object array”using UnityEngine;using Tsukimi;
public class ArraysElementInObjectArray : TsukimiBehaviour{ private object[] boxes;
void Start() { int[] scores = new int[4]; boxes = new object[2]; boxes[0] = scores; }}Passing to other Behaviours
Section titled “Passing to other Behaviours”Writing by specifying a name
Section titled “Writing by specifying a name”Specify the other Behaviour’s variable name as a string to write the array.
using UnityEngine;using Tsukimi;
public class ArraysSetProgramVariable : TsukimiBehaviour{ public TsukimiBehaviour other;
void Start() { int[] scores = new int[] { 1, 2, 3 }; other.SetProgramVariable("values", scores); }}Reading by specifying a name
Section titled “Reading by specifying a name”The return value is object, so you need to convert it when you receive it.
using UnityEngine;using Tsukimi;
public class ArraysGetProgramVariable : TsukimiBehaviour{ public TsukimiBehaviour other;
void Start() { int[] got = (int[])other.GetProgramVariable("values"); Debug.Log(got.Length); }}Specifying as an argument to a network event
Section titled “Specifying as an argument to a network event”If you add [NetworkCallable] to the receiving method, you can pass an array as an argument.
using UnityEngine;using Tsukimi;using VRC.Udon.Common.Interfaces;using VRC.SDK3.UdonNetworkCalling;
public class ArraysSendAsNetworkEvent : TsukimiBehaviour{ private int[] scores;
void Start() { scores = new int[] { 1, 2, 3 }; SendCustomNetworkEvent(NetworkEventTarget.All, nameof(Receive), scores); }
[NetworkCallable] public void Receive(int[] values) { Debug.Log(values.Length); }}