はじめに
Unityでゲームを作っていると、アイテムの一覧や敵のステータス、プレイヤーのスコアなど、「データをどう整理するか」という課題に必ずぶつかります。
小規模なゲームなら配列(Array)で十分かもしれませんが、プロジェクトが大きくなるにつれて「もっと柔軟に管理したい!」と思う瞬間が出てきますよね。
そこで登場するのが、ListやDictionaryといった便利なデータ構造です。これらを正しく使い分けることで、コードがスッキリして開発効率がグッと上がります。逆に、特徴を理解せずに使ってしまうと「バグの温床」や「管理のしづらさ」につながることも…。
この記事では、Unity C#における配列・リスト・辞書の基本と使い分けをわかりやすく解説します。さらに、開発現場で役立つ具体的なコード例や、作業をラクにしてくれるおすすめアセット・参考書籍もご紹介します。
「効率的にデータを管理したい!」と思っている方は、ぜひ最後まで読んでみてくださいね✨
Unityで使えるデータ構造の比較と使い分け
Unity C#には、データをまとめて扱うためのさまざまなデータ構造があります。代表的なのは「配列(Array)」「リスト(List<T>)」「辞書(Dictionary<TKey, TValue>)」ですが、他にも「Queue」「Stack」「HashSet」などの便利な仕組みが存在します。
ここでは、それぞれの特徴と「どんな場面で使うべきか」をわかりやすく整理してみましょう。
| データ構造 | 特徴 | 使いどころ |
|---|---|---|
| 配列 (T[]) | 固定長でメモリ効率が良い。高速なインデックスアクセス (array[i]) が可能。 | 要素数が最初から決まっている場合、処理速度を重視したい場合。 |
| リスト (List<T>) | 可変長で柔軟。Add()やRemove()で簡単に要素を追加・削除できる。 | 頻繁に要素を増減させたいとき。最もよく使われるデータ構造。 |
| 辞書 (Dictionary<TKey, TValue>) | キーと値のペアで管理。インデックスではなくキーで検索。高速な探索が可能。 | IDや名前など「一意のキー」でデータを管理したいとき。 |
| キュー (Queue<T>) | FIFO(先入れ先出し)方式でデータを処理。 | 処理待ちリスト、イベントの順番管理。 |
| スタック (Stack<T>) | LIFO(後入れ先出し)方式。直前のデータをすぐ取り出せる。 | アンドゥ/リドゥ機能、履歴管理。 |
| HashSet<T> | 重複を許さない。高速な検索が可能。順序なし。 | 一意性を保ちたいデータ集合の管理。 |

こうして比較してみると、それぞれの得意分野がよくわかります。
「データの数が決まっているなら配列」「柔軟に増減したいならリスト」「名前やIDで検索したいなら辞書」というイメージを持っておくと便利です。
補足:データ管理をさらに快適にしたい方は、セーブ機能を超簡単に追加できるアセットEasy Save 3もおすすめです。リストや辞書のデータをまとめて保存できるので、ゲーム開発では欠かせない存在になっています。
Dictionary(辞書)の使い方と実例
Dictionaryは、配列やリストのようにインデックス番号で管理するのではなく、キー(Key)と値(Value)のペアでデータを扱える便利なコレクションです。
ゲーム開発では「アイテム名と価格」「プレイヤーIDとスコア」のように、名前やIDで管理したいときにとても役立ちます。
基本の書き方
// 宣言と初期化
Dictionary<string, int> dic = new Dictionary<string, int>()
{
{ "Apple", 150 },
{ "Orange", 100 },
{ "Peach", 250 }
};
このように、キーに文字列、値に整数を設定する例です。もちろん型は自由に組み合わせ可能です。
要素の追加
// 新しい要素を追加
dic.Add("Banana", 50);
Addを使えば簡単に要素を追加できます。ただし同じキーは二度追加できないので注意しましょう。
要素の取得
// キーを指定して値を取得
int price = dic["Banana"];
Debug.Log(price); // 50
キーを指定すれば、インデックス番号を使わずに直接値を取り出せます。
ループで全データを確認
// KeyとValueをまとめて取り出す
foreach (KeyValuePair<string, int> item in dic)
{
Debug.Log(item.Key + " : " + item.Value);
}
foreachを使うと、すべてのキーと値をまとめてチェックできます。
辞書にはインデックス番号の概念がないため、ループ処理は基本的にforeachを使います。
要素の削除
dic.Remove("Banana");
Removeを使えば、指定したキーごと削除できます。
実践例:アイテム管理
// アイテム名をキーに、在庫数を管理する
Dictionary<string, int> itemStock = new Dictionary<string, int>()
{
{ "Potion", 10 },
{ "Elixir", 3 },
{ "Key", 1 }
};
// アイテムの在庫を確認
if (itemStock.ContainsKey("Potion"))
{
Debug.Log("ポーションは " + itemStock["Potion"] + " 個あります");
}

このように辞書を使うと「アイテム名 → 個数」といった分かりやすい管理ができます。
ゲームのインベントリやプレイヤーデータ管理などで大活躍しますよ!
便利アセット紹介:辞書やリストの中身をUnityエディタ上で見やすくしたい方にはOdin Inspectorがピッタリです。
InspectorにそのままDictionaryを表示できるので、デバッグやチューニングが圧倒的に効率化します。
List(リスト)の使い方と実例
List<T>は、配列に近い操作感で使える可変長コレクションです。
ゲーム中に「敵を追加」「倒したら削除」「所持アイテムを並べ替え」のように、要素数が変化する場面に最適です。
基本の書き方
// 宣言と初期化
List<int> numbers = new List<int>();
// 要素の追加
numbers.Add(10);
numbers.Add(20);
// 複数一括追加(配列や別のコレクション)
numbers.AddRange(new int[] { 30, 40, 50 });
// 要素数
Debug.Log(numbers.Count); // 5
要素の取得とループ
// インデックスで取得
int first = numbers[0]; // 10
// forループ(順番にアクセスしたいとき)
for (int i = 0; i < numbers.Count; i++)
{
Debug.Log(i + " : " + numbers[i]);
}
// foreach(中身をなめたいとき)
foreach (int n in numbers)
{
Debug.Log(n);
}
削除まわり(よく使うパターン)
// 値を指定して最初の1つを削除
numbers.Remove(20);
// 条件に一致する全てを削除(ラムダ式)
numbers.RemoveAll(n => n < 30);
// インデックスを指定して削除
numbers.RemoveAt(0);
// 全消去
numbers.Clear();
実践例:敵リストの管理
using System.Collections.Generic;
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
// 生成した敵を管理
public List<GameObject> enemies = new List<GameObject>();
// 敵の登録
public void Register(GameObject enemy)
{
if (!enemies.Contains(enemy))
{
enemies.Add(enemy);
}
}
// 倒された敵を外す
public void Unregister(GameObject enemy)
{
enemies.Remove(enemy);
}
// 画面外に出た敵を一括削除(毎フレーム軽くチェック)
void Update()
{
enemies.RemoveAll(e => e == null); // 破棄済みを除外
enemies.RemoveAll(e => e.transform.position.y < -20f);
}
// すべてにバフを付与(ループ例)
public void ApplyBuff(float scale)
{
foreach (var e in enemies)
{
if (e != null)
{
e.transform.localScale *= scale;
}
}
}
}

このようにListは「増やす・探す・消す」が直感的で、戦闘の出入りが多いゲームにぴったり。
Containsで重複登録を防ぐ、RemoveAllで条件削除、というのが定番テクです。
コードを書かずにデータ操作したい方へ:
ビジュアルスクリプティングのPlaymakerなら、List相当のコレクション操作(追加・削除・検索)をノードで直感的に扱えます。
プロトタイピングや非エンジニアとの共同作業で大活躍します。
応用:自作Dictionary(順序付き辞書)の例
標準のDictionaryは便利ですが、インデックス番号によるアクセスができないため「順番通りに扱いたい」ケースでは不便に感じることがあります。
そこで、リストを組み合わせた自作のDictionary風クラスを作って、キーと値を順序付きで管理する方法を紹介します。
サンプル:MyDictionaryクラス
using System.Collections.Generic;
public class MyDictionary
{
private List<string> keys = new List<string>();
private List<int> values = new List<int>();
public int Count => keys.Count;
// 要素を追加
public void Add(string key)
{
if (keys.Contains(key))
{
int index = keys.IndexOf(key);
values[index]++;
}
else
{
keys.Add(key);
values.Add(1);
}
}
// 特定のキーを持っているか確認
public bool Contains(string key)
{
return keys.Contains(key);
}
// キーからインデックスを取得
public int GetIndexByKey(string key)
{
return keys.IndexOf(key);
}
// インデックスからキーを取得
public string GetKeyByIndex(int index)
{
return keys[index];
}
// インデックスから値を取得
public int GetValueByIndex(int index)
{
return values[index];
}
}
使い方の例
// 宣言
MyDictionary myDic = new MyDictionary();
// アイテムを追加
myDic.Add("Potion");
myDic.Add("Potion");
myDic.Add("Elixir");
// 出力
for (int i = 0; i < myDic.Count; i++)
{
UnityEngine.Debug.Log(myDic.GetKeyByIndex(i) + " : " + myDic.GetValueByIndex(i));
}
// → Potion : 2
// → Elixir : 1
このように自作のクラスを使えば「辞書の便利さ」と「リストの順序管理」を組み合わせることができます。

標準ライブラリではOrderedDictionaryというクラスも存在しますが、Unity環境では互換性が限定的な場合があるため、必要に応じて自作してみるのもおすすめです。
補足:標準のDictionaryを使う場合でも、Odin Inspectorのような拡張アセットを導入するとInspector上で中身を視覚的に管理できるため、実務的にはそれで十分なケースも多いです。
学習におすすめの書籍
配列・リスト・辞書などのデータ構造を正しく理解するには、実際に手を動かしながら学ぶのが一番です。
ここでは、Unity C#の基礎をしっかり固めたい方におすすめの参考書を紹介します📚
Unityの教科書 Unity 6完全対応版
初心者に大人気の入門書シリーズ。Unityの最新バージョンに対応しており、基本操作からC#スクリプトの書き方まで一冊で学べます。
「Unityはじめてさん」に特におすすめです。
✅ Amazonでチェックする | ✅ 楽天でチェックする
Unity 3Dゲーム開発ではじめるC#プログラミング
Unityを使いながらC#の基礎文法を体系的に学べる一冊。配列やリスト、辞書といったコレクションの使い方も丁寧に解説されています。
「C#もしっかり理解してスキルを伸ばしたい」という方にピッタリです。
✅ Amazonでチェックする | ✅ 楽天でチェックする
まとめ
今回は、Unity C#における配列・リスト・辞書の特徴と使い分けについて解説しました。 それぞれのポイントをおさらいしてみましょう。
- 配列(Array):固定長。処理速度とメモリ効率を重視するなら最適。
- List<T>:可変長。要素の追加・削除が柔軟で、最も使われるデータ構造。
- Dictionary<TKey, TValue>:キーと値で管理。検索や管理に便利。
- Queue / Stack / HashSet:用途に応じた特化型のデータ構造。
重要なのは「どのデータ構造を選ぶかは用途次第」ということ。 例えば「敵リストの管理」ならList、「アイテム名と個数」ならDictionary、といったように、状況に応じて選び分けましょう。
便利なアセットや書籍も併用しながら、自分に合ったデータ管理スタイルを確立してくださいね✨
あわせて読みたい
データ管理まわりの理解を深めたい方へ、あわせて読むと役立つ記事をピックアップしました。
- Unityのシリアライズ完全ガイド!データの保存・読み込みを自由自在に
- Unityのデータ管理を最適化!SerializableとScriptableObjectの違いと活用法
- 【実践】UnityでJSONデータ管理!セーブ&ロードを最適化する方法
- Unityで外部CSVファイルを読み込む方法|初心者向けにわかりやすく解説!
よくある質問(FAQ)
- QListと配列、どっちを使えばいいの?
- A
要素数が最初から決まっていて変わらないなら配列、途中で増減する可能性があるならListがおすすめです。 ゲーム開発では柔軟なListを使うケースが多いですが、パフォーマンス重視なら配列が有利になる場面もあります。
- QDictionaryのキーに同じ値を登録できる?
- A
できません。同じキーは一度しか持てない仕組みになっています。 もし「同じキーで複数の値を管理したい」場合は、
Dictionary<string, List<T>>のように「キー+リスト」を組み合わせると便利です。
- Qアセットは必ず必要ですか?
- A
必須ではありませんが、開発効率を大きく高めてくれます。 たとえば、Easy Save 3を使えばデータ保存が数行で実装でき、Odin Inspectorなら辞書やリストをInspectorで直感的に確認できます。 「時間を買う」という意味で導入を検討する価値は大いにありますよ✨







※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。