コンテンツにスキップ

配列

配列は、同じ型の値を、最初に決めた数だけ並べて持つ型です。長さはあとから変えられません。

List や Dictionary は使えないので、複数の値をまとめて持つときは配列を使います。

書き方説明
new int[4]長さを決めた生成
new int[count]長さを変数で決めた生成
new int[] { 1, 2, 3 }初期値を並べた生成
int[] a = { 1, 2, 3 }宣言と同時の初期化
new[] { 1, 2, 3 }要素の型の推論
var a = new int[4]変数の型の推論
new int[4][]配列の配列の生成
new int[][] { ... }配列の配列の初期化
new int[2][][]3 段の入れ子
new int[2][][][]4 段の入れ子
new int[4, 4]2 次元配列の生成
new string[4]要素が参照型
new Vector3[4]要素が構造体
new GameObject[4]要素が実行環境の型
a[0] = 10要素への書き込み
int x = a[0]要素の読み出し
a[0] += 10複合代入
a[0]++増減
a[i] = 10変数による添字の指定
a[^1]末尾からの添字
a[1..]範囲の切り出し
points[0].x = 5f構造体の要素のフィールドへの書き込み
Vector3 v = points[0]構造体の要素の取り出し
a.Length要素数の取得
a.Rank次元数の取得
a.GetLength(0)指定した次元の長さの取得
a.GetValue(0)型を問わない読み出し
a.SetValue(9, 0)型を問わない書き込み
a.Clone()複製
System.Array.Copy(a, b, 3)別の配列への複写
System.Array.Clear(a, 0, 3)範囲の初期化
foreach (int v in a)全要素の走査
foreach (var v in a)型を推論させた走査
for (int i = 0; i < a.Length; i++)添字による走査
private int[] bufferフィールドとして保持
public GameObject[] targets公開フィールドへの差し込み
[UdonSynced] private int[] values同期
Fill(scores)引数としての受け渡し
params int[] values可変個の引数での受け取り
int[] Make()戻り値での返却
int[] alias = original別の変数への代入
a == nullnull との比較
object boxed = scoresobject への格納
object[] boxes = names要素の型が広い配列への代入
boxes[0] = scoresobject の配列の要素への格納
other.SetProgramVariable("values", a)名前を指定した書き込み
(int[])other.GetProgramVariable("values")名前を指定した読み出し
SendCustomNetworkEvent(..., a)ネットワークイベントの引数への指定
書き方説明エラー理由
int[,,] a = new int[2, 2, 2];3 次元以上の多次元配列TUKI0001未実装
new int[2, 2] { { 1, 2 }, { 3, 4 } }2 次元配列の初期値の並べ書きTUKI0001未定
foreach (int v in grid)2 次元配列の走査TUKI0001設計
Swap(ref a)自作メソッドへ ref で渡すTUKI0001環境
Make(out int[] b)自作メソッドから out で受けるTUKI0001環境
Bump(ref a[0])要素を ref で渡すTUKI0001環境
boxed is Vector3[]配列型かどうかの型テストTUKI0001未実装
System.Array.IndexOf(a, 1)要素を探すTUKI0001未実装
System.Array.Reverse(a)並びを逆にするTUKI0001未実装
System.Array.Sort(a)並べ替えるTUKI0001未実装
System.Array.Resize(ref a, 5)長さを変えるTUKI0001未定
new List<int>()List(可変長の並び)TUKI0102, TUKI0101環境
new Dictionary<int, int>()DictionaryTUKI0102, TUKI0101環境
using System.Linq;LINQ のクエリ式CS0234(名前空間そのものが無い)環境
foreach (int v in list)配列以外をたどるTUKI0001, TUKI0101, TUKI0102環境
s[^1]文字列の末尾からの添字TUKI0001未実装
points[1..]構造体の配列の切り出しTUKI0001未実装
System.Index i = 0;位置を表す型TUKI0102, TUKI0101, TUKI0099環境
System.Range r = 0..1;範囲を表す型TUKI0102, TUKI0099環境
使いたい形代わり
List長めに取った配列と、いま何個入っているかの変数
DictionaryKey が小さい整数や列挙型なら、Key を添字にした配列。そうでなければ Key の配列と Value の配列を対で持ち、順に探す
3 次元以上の配列配列の配列(int[2][][])、または z * w * h + y * w + x で 1 本の配列
2 次元配列の走査GetLength(0)GetLength(1) を使った二重の for
refout による書き換え配列を渡して中身を書き換えるか、戻り値で返す
using UnityEngine;
using Tsukimi;
public class ArraysDeclareFixedLength : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[4];
}
}
using UnityEngine;
using Tsukimi;
public class ArraysDeclareVariableLength : TsukimiBehaviour
{
public int count = 4;
private int[] scores;
void Start()
{
scores = new int[count];
scores[0] = 10;
}
}
using UnityEngine;
using Tsukimi;
public class ArraysDeclareInitializer : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[] { 1, 2, 3 };
}
}

宣言と同時に書くときは new int[] を省けます。

using UnityEngine;
using Tsukimi;
public class ArraysDeclareShortInitializer : TsukimiBehaviour
{
private int[] scores = { 1, 2, 3 };
void Start()
{
scores[0] = 10;
}
}
using UnityEngine;
using Tsukimi;
public class ArraysDeclareInferredInitializer : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new[] { 1, 2, 3 };
}
}
using UnityEngine;
using Tsukimi;
public class ArraysDeclareVar : TsukimiBehaviour
{
private int[] scores;
void Start()
{
var made = new int[4];
made[0] = 10;
scores = made;
}
}
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
}
}
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;
}
}
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;
}
}

段数に上限はありません。

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
}
}

次元は 2 つまでです。要素を 1 個ずつ箱に入れて出し入れするので、同じ大きさの 1 次元配列や配列の配列より命令が増えます。

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
}
}
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"
}
}
using UnityEngine;
using Tsukimi;
public class ArraysElementStructType : TsukimiBehaviour
{
void Start()
{
Vector3[] points = new Vector3[4];
points[0] = new Vector3(1f, 2f, 3f);
}
}

実行環境が公開している型も要素にできます。

using UnityEngine;
using Tsukimi;
public class ArraysElementObjectType : TsukimiBehaviour
{
void Start()
{
GameObject[] targets = new GameObject[4];
targets[0] = gameObject;
}
}
using UnityEngine;
using Tsukimi;
public class ArraysWriteElement : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[4];
scores[0] = 10;
}
}
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
}
}
using UnityEngine;
using Tsukimi;
public class ArraysCompoundAssign : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[4];
scores[0] += 10;
}
}
using UnityEngine;
using Tsukimi;
public class ArraysIncrementElement : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[4];
scores[0]++;
}
}
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;
}
}

^1 が最後の要素です。a[a.Length - 1] と同じ位置を指します。

using UnityEngine;
using Tsukimi;
public class ArraysIndexFromEnd : TsukimiBehaviour
{
void Start()
{
int[] a = { 1, 2, 3 };
Debug.Log(a[^1]); // => 3
}
}

新しい配列が作られて、指定した範囲の要素がそこへ写ります。元の配列は変わりません。

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
}
}

構造体の要素のフィールドへの書き込み

Section titled “構造体の要素のフィールドへの書き込み”
using UnityEngine;
using Tsukimi;
public class ArraysStructElementFieldWrite : TsukimiBehaviour
{
void Start()
{
Vector3[] points = new Vector3[4];
points[0].x = 5f;
}
}

変数へ入るのは複製なので、その変数を書き換えても配列の要素は変わりません。

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); // => 実行環境の値
}
}
using UnityEngine;
using Tsukimi;
public class ArraysLength : TsukimiBehaviour
{
void Start()
{
int[] scores = new int[4];
int n = scores.Length;
Debug.Log(n); // => 4
}
}
using UnityEngine;
using Tsukimi;
public class ArraysRank : TsukimiBehaviour
{
void Start()
{
int[] scores = new int[4];
int r = scores.Rank;
Debug.Log(r); // => 1
}
}
using UnityEngine;
using Tsukimi;
public class ArraysGetLength : TsukimiBehaviour
{
void Start()
{
int[] scores = new int[4];
int n = scores.GetLength(0);
Debug.Log(n); // => 4
}
}

戻り値は object なので、使うときは変換が要ります。

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
}
}
using UnityEngine;
using Tsukimi;
public class ArraysSetValue : TsukimiBehaviour
{
private int[] scores;
void Start()
{
scores = new int[3];
scores.SetValue(9, 0);
}
}

戻り値は object なので、使うときは変換が要ります。

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[]
}
}
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);
}
}
using UnityEngine;
using Tsukimi;
public class ArraysArrayClear : TsukimiBehaviour
{
void Start()
{
int[] scores = new int[] { 1, 2, 3 };
System.Array.Clear(scores, 0, 3);
}
}
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
}
}
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
}
}
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
}
}
using UnityEngine;
using Tsukimi;
public class ArraysFieldPrivate : TsukimiBehaviour
{
private int[] buffer;
void Start()
{
buffer = new int[16];
buffer[0] = 10;
}
}

public なフィールドは編集画面に出て、そこから値を設定できます。

using UnityEngine;
using Tsukimi;
public class ArraysFieldPublic : TsukimiBehaviour
{
public GameObject[] targets;
void Start()
{
targets[0] = gameObject;
}
}

同期の方式を指定しなければ、既定の方式になります。

using UnityEngine;
using Tsukimi;
public class ArraysFieldSynced : TsukimiBehaviour
{
[UdonSynced] private int[] values = new int[4];
void Start()
{
values[0] = 10;
RequestSerialization();
}
}
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;
}
}
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;
}
}
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];
}
}
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
}
}
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
}
}

配列は参照なので、object の変数へそのまま入ります。

using UnityEngine;
using Tsukimi;
public class ArraysStoreInObject : TsukimiBehaviour
{
void Start()
{
int[] scores = new int[4];
object boxed = scores;
Debug.Log(boxed); // => System.Object[]
}
}

string[]object[] として扱えます。要素の型が広がる向きにだけ通ります。

using UnityEngine;
using Tsukimi;
public class ArraysCovariantAssign : TsukimiBehaviour
{
void Start()
{
string[] names = new string[4];
object[] boxes = names;
Debug.Log(boxes.Length); // => 4
}
}
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;
}
}

相手の Behaviour の変数名を文字列で指定して、配列を書き込みます。

using UnityEngine;
using Tsukimi;
public class ArraysSetProgramVariable : TsukimiBehaviour
{
public TsukimiBehaviour other;
void Start()
{
int[] scores = new int[] { 1, 2, 3 };
other.SetProgramVariable("values", scores);
}
}

戻り値は object なので、受けるときに変換が要ります。

using UnityEngine;
using Tsukimi;
public class ArraysGetProgramVariable : TsukimiBehaviour
{
public TsukimiBehaviour other;
void Start()
{
int[] got = (int[])other.GetProgramVariable("values");
Debug.Log(got.Length);
}
}

ネットワークイベントの引数への指定

Section titled “ネットワークイベントの引数への指定”

受け手のメソッドに [NetworkCallable] を付けておくと、配列を引数として渡せます。

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);
}
}