配列を極める!知っておくと得するテクニック
配列を極める!知っておくと得するテクニック
はじめに
配列は、ゲーム開発やプログラミングの基礎中の基礎と言えます。Unityを使っていると「敵キャラクターを複数まとめたい」「スコア履歴を保管したい」など、同じ型のデータをまとめて扱うケースがしばしば発生します。そのときに頼りになるのが、**配列(Array)やリスト(List)**といったコレクションです。
ただ、「配列」と一口に言っても、C#ではバリエーションが豊富です。多次元配列、List<T>
やDictionary<TKey,TValue>
など、用途や目的別に選択肢が多く、「何をどう使えばいいかわからない」ままなんとなく書いている人も少なくありません。本記事ではUnityでのゲーム作りを想定しつつ、配列の基本から応用テクニックまでを分かりやすくまとめます。
なぜ配列が重要なのか?
Unityでゲームを作るとき、キャラクターのステータスや敵の出現パターンなど、「同じ型のデータをまとめて管理したい」シーンがたくさん出てきます。配列を使いこなせるかどうかで、コードのわかりやすさ・メンテナンス性・処理効率が大きく変わるのです。
- ステージごとの情報(敵の種類や出現順序)
- アイテム一覧(名前・効果・数値など)
- プレイヤーの過去スコアや履歴
これらを一つひとつ別の変数で管理すると、あとで「追加してほしいデータがある!」と言われた際にコード全体を修正しなくてはなりません。配列でまとめておけば、新要素を増やしやすく、処理のループも書きやすくなります。
代表的な配列やコレクション
int[] scores
1. 一次元配列 C#のシンプルな配列。要素数が固定されており、宣言時にサイズを決定します。
int[] scores = new int[5];
scores[0] = 100;
scores[1] = 200;
- メリット: メモリに連続して格納されるためアクセスが速い
- デメリット: サイズを後から変更できない
int[,] matrix
2. 多次元配列 2Dゲームやマップタイル管理で活躍。
int[,] mapData = new int[3, 5];
mapData[0,2] = 1;
要素数が固定なので、タイル数が変化するような処理にはあまり向きません。
List<T>
動的配列
3. C#ならではの便利コレクション。要素の追加・削除が自由で、サイズも動的に変わります。
List<string> enemies = new List<string>();
enemies.Add("Slime");
enemies.Add("Goblin");
- メリット: 要素数を増減しやすい、LINQなどと組み合わせやすい
- デメリット: メモリは動的に再確保されるため、大規模処理のパフォーマンス注意
4. 他にもあるコレクション
-
Dictionary<TKey,TValue>
: キーバリュー型で素早い検索 -
HashSet<T>
: 重複回避が得意 -
Queue<T>
/Stack<T>
: 先入先出、後入先出に特化
まずは配列とList<T>
を中心に押さえれば、ゲーム制作で困ることはほぼなくなるでしょう。
よくあるつまずきポイント
1. インデックス範囲外のエラー
配列の要素数を超えたインデックスにアクセスすると、IndexOutOfRangeExceptionが発生します。たとえばスコア配列の範囲を超えた値を扱おうとしてゲームがクラッシュする、というのが典型的な事故。
- 例:
scores[5]
(実際の要素数は5なら、最大インデックスは4なのでアウト)
2. サイズ変更できない
既存の配列にあと1要素だけ追加したい、と思っても直接は不可能。
int[] newArr = new int[oldArr.Length + 1];
// 旧配列の内容をコピー → 面倒!
こうした場合、多くの人がList<T>
を使うべきだと気づかず、手動で配列を再生成してコピーする羽目になったりします。
3. 多次元配列と配列の配列を混同
C#には多次元配列と**配列の配列(ジャグ配列)**の2種類があり、使い分けを誤ると意図しないデータ構造になりがち。特に2Dマップを扱うとき、「縦横サイズが可変なマップ」なのに多次元配列を使ってしまい、後から変更しにくい状況が生まれることがあります。
4. パフォーマンス面の誤解
配列が一番軽量だから何でも配列で書く、という誤解をしていると、逆に開発速度が落ちたり、やたらと複雑なロジックになる場合が多いです。適切なコレクションを選ぶことが最適化にもつながります。
効率的な解決策
List<T>
を優先
1. 配列のサイズが変わるなら「要素が増えたり減ったり」する用途ならList<T>
がベスト。
List<int> dynamicScores = new List<int>();
dynamicScores.Add(100);
dynamicScores.Add(200);
サイズ変更が自由なので、あとから追加・削除を繰り返してもOK。
2. インデックスを操作するときは条件をチェック
複数の要素をループするときでも、インデックスを手動で扱う場合は必ず0 <= index < 配列.Length
を確認するよう癖をつけておくと事故が激減します。
3. 多次元配列 vs ジャグ配列を正しく選ぶ
-
多次元配列 (例:
int[,] matrix
)- すべての次元が同じサイズ。行列計算や固定サイズのタイルマップなどに向く
-
ジャグ配列 (例:
int[][] jagArr
)- 各行(あるいは列)が異なる長さを持てる。可変サイズが必要なとき便利
foreach
ループで安全に取り扱う
4. 要素を単に回したいだけなら、for
よりforeach
のほうが安全で可読性も高い。インデックスのミスが起きにくいので、初心者には特におすすめ。
foreach(var score in scores)
{
Debug.Log(score);
}
実践例:敵のウェーブ管理
ゲームでよくある「敵がウェーブごとに出現する」状況を考えます。
- 波ごとに異なる敵を2D配列やジャグ配列で管理しても良いし、リストの中に新たなリストを入れる方法もあります。
- 「Wave1: スライム5体 → Wave2: ゴブリン3体&アーチャー2体」など変則的な組み合わせなら、ジャグ配列や
List<List<Enemy>>
が便利。 - スライムやゴブリンの情報はscriptable objectなどに紐づけておけば、インデックスだけ参照して
Instantiate
可能。
やってはいけない無理矢理実装
- むやみに2D配列を使っているのに、途中で列数や行数を変更したい → フルコピーが必要
- 多数の要素を扱うのに一次元配列だけで管理 → 追加や削除のたびに再生成という悲劇
- インデックス指定を乱用し、
IndexOutOfRangeException
を連発する
こういった失敗事例は珍しくありません。プロジェクトの要求に応じた適切なデータ構造を選択するのが重要です。
まとめ:配列選びと扱いを見直すだけで開発がスムーズに
配列を使いこなすとは、「固定サイズの一次元配列」「可変のリスト」「ジャグ配列」「多次元配列」を用途別に上手に選び、保守しやすいコードに仕上げることです。何千行ものスクリプトを書く前に、データ構造をちゃんと考えておくだけで、後々の手戻りを大きく削減できます。
- ゲーム中の「同じ型のデータ」をまとめる場合は配列やリストを積極的に活用
- サイズが変動するなら
List<T>
一択、固定長なら素直に配列でOK - 2Dや3Dのマップデータを扱うときは多次元配列かジャグ配列を正しく選択
- インデックスエラーに注意し、
foreach
で安全運転
そうしたポイントを常に意識しておけば、「あとで追加要素を入れるのが地獄だった…」といった悲しい目に遭う可能性がぐっと減るでしょう。
この記事で学んだことを活かし、さらに実践したい方へ
Unity開発を効率化するには、実践的なスキル共有やコミュニティでの情報交換が重要です。
おすすめのステップは以下の3つです。
1. 有料教材「どこでもUnity教室」でスキルを一気に伸ばす
- 5日間でFPSを完成:初心者向けに要点を凝縮
- C#・最新InputSystem・FPS実装などもカバー
- 特典:Discord招待+サンプルプロジェクトDLで疑問解消
Unity初心者が5日で3D FPSを完成できる入門チュートリアル
2. 無料コミュニティで疑問解消&モチベーション維持
- 初心者~中級者まで歓迎:ペースに合わせて学べる
- 質問サポート完備:不明点をすぐ仲間に相談
- 学習仲間と切磋琢磨:楽しく続けられる環境
Discordサーバーへの参加はこちら
3. “ゲーム開発所RYURYU”がトータルサポート
- ココナラ販売実績200件超:幅広いUnity開発を受注
- VR/AR/AIなど最新領域にも精通:深いノウハウを提供
- ゲームクリエイター甲子園や東京ゲームショウ出展経験多数
詳しいご相談はこちら
配列は地味な要素に見えますが、うまく使うことでゲーム開発が一段とスムーズになります。プロジェクトの要件に応じた最適な形を選び、データ管理を進めていきましょう。小さな工夫が、成功への大きな一歩となるはずです。
Discussion