1. はじめに
UnityでC#を使ってゲームを開発するとき、コードをシンプルで分かりやすく書くことはとても大事です。特に、ゲーム内でオブジェクトを管理したり、データを扱う処理が増えてくると、コードが長くなりがちですよね。そんなときに便利なのが ラムダ式 と LINQ(Language Integrated Query) です。
ラムダ式を使えば、短くてスッキリしたコードを書けるようになり、イベント処理やリスト操作が簡単になります。また、LINQを活用すると、配列やリストのデータを検索・フィルタリング・ソートするときに、直感的で分かりやすい書き方ができます。
例えば、ゲーム内の敵キャラクターのリストからHPが高い順に並び替えたり、特定の条件に合うオブジェクトだけを取り出す場合、通常のループ処理を書くよりも LINQを使ったほうが簡潔で読みやすくなる ことが多いです。
しかし、ラムダ式やLINQを適当に使うと 処理が重くなったり、デバッグが難しくなったりする こともあります。そのため、使い方だけでなく、注意点も知っておくことが大切です。
この記事では、Unityでラムダ式とLINQを どのように活用できるのか 、そして どんな点に気をつけるべきか を初心者にも分かりやすく解説していきます。ぜひ、最後まで読んで、コードをもっと効率よく書けるようになりましょう!
2. ラムダ式とは?
ラムダ式とは、簡潔に書ける関数のようなものです。C#では、通常のメソッドを定義する代わりに、短いコードで処理を記述できます。
特に、Unityのスクリプトでは、イベント処理やリスト操作を簡単にするために役立ちます。
基本構文
ラムダ式の書き方は、以下のようになります。
(引数) => { 処理 }
例えば、次のような関数があるとします。
int MultiplyByTwo(int x) {
return x * 2;
}
これをラムダ式を使って書くと、以下のように短くできます。
x => x * 2
この場合、x
という引数を受け取り、それを2倍にして返すという意味になります。
Unityスクリプトでの活用シーン
① ボタンのクリックイベント
通常、UnityのUIボタンにクリックイベントを設定するには、以下のようにメソッドを用意します。
void OnButtonClick() {
Debug.Log("ボタンが押されました");
}
button.onClick.AddListener(OnButtonClick);
しかし、ラムダ式を使えば、より簡潔に記述できます。
button.onClick.AddListener(() => Debug.Log("ボタンが押されました"));
ラムダ式を使うことで、別途メソッドを用意せずに、イベントの中で直接処理を書くことができます。
② コルーチンの省略記法
Unityのコルーチン(IEnumerator
)を使う際、通常は以下のように書きます。
IEnumerator WaitAndPrint() {
yield return new WaitForSeconds(2);
Debug.Log("2秒後に表示");
}
StartCoroutine(WaitAndPrint());
しかし、ラムダ式と無名関数を使うと、一行で書くことができます。
StartCoroutine((IEnumerator)(() => { yield return new WaitForSeconds(2); Debug.Log("2秒後に表示"); }));
これは少し複雑ですが、簡単なコルーチンを素早く記述したいときに便利です。
③ 条件検索時の簡略化
例えば、ゲーム内で「HPが50以上の敵だけを取得したい」といった場合、通常は次のように書きます。
List<Enemy> strongEnemies = new List<Enemy>();
foreach (Enemy enemy in enemies) {
if (enemy.HP > 50) {
strongEnemies.Add(enemy);
}
}
しかし、ラムダ式とLINQを使えば、以下のようにシンプルに記述できます。
var strongEnemies = enemies.Where(e => e.HP > 50).ToList();
このように、ラムダ式を活用すると、コードの可読性が向上し、スクリプトがスッキリします。
まとめ
- ラムダ式を使うと、短いコードで処理を記述できる。
- Unityでは、イベント処理やリストのフィルタリングなどで便利。
- ただし、可読性が落ちることもあるため、適切に使うことが大切。

次のセクションでは、LINQを活用したデータ操作について詳しく解説します!
3. LINQとは?
Unityのスクリプトを書くとき、リストや配列のデータを扱うことが多いですよね。例えば、「HPが50以上の敵キャラだけを選びたい」「名前順に並べたい」といった処理をする場面があると思います。
そんなときに便利なのが LINQ(Language Integrated Query) です!
LINQの基本概念
LINQは、C#の標準機能のひとつで、リストや配列といったコレクションに対して、SQLのような直感的な記述でデータの検索や並び替えができる機能です。
通常、リストのデータを処理するにはforループを使いますが、LINQを使うと シンプルな1行のコードで同じことができます!
LINQの基本構文
まず、LINQの基本的な書き方を見てみましょう。
var result = list.Where(x => x > 10).ToList();
このコードでは、list
の中から x > 10
(10より大きい値)を持つ要素だけを取り出し、新しいリスト result
にしています。
ポイントは Where(x => 条件)
という書き方。これがLINQのフィルタリングの基本です。
Unityでの活用例
では、UnityでLINQをどのように使うのか、具体的な例を見ていきましょう。
1. ゲームオブジェクトのリストから特定の条件に合うものを抽出
例えば、シーン内の敵キャラクターの中からHPが50以上の敵だけを取得したい場合、通常はforループを使って条件分岐を書きますが、LINQを使うと簡潔になります。
通常のforループを使った場合
List<GameObject> strongEnemies = new List<GameObject>();
foreach (var enemy in enemies)
{
if (enemy.GetComponent<Enemy>().HP > 50)
{
strongEnemies.Add(enemy);
}
}
LINQを使った場合
var strongEnemies = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
このように、1行でリストのフィルタリングができて、とてもスッキリしたコードになります!
2. オブジェクトの並び替え
プレイヤーのランキングやキャラクターのステータス画面などで、リストのデータを並び替えたい場合もありますよね。
LINQの OrderBy()
を使うと、簡単に並び替えができます。
例えば、キャラクターのリストをレベル順に並べ替えたい場合:
var sortedCharacters = characters.OrderBy(c => c.Level).ToList();
降順(レベルが高い順)にしたい場合は?
var sortedCharacters = characters.OrderByDescending(c => c.Level).ToList();
OrderBy()
を使うと、データの並び替えが1行でできるので、とても便利ですね!
3. 名前が「A」で始まるオブジェクトを探す
キャラクターの名前の中から、「A」で始まるものだけをリスト化したい場合は、 StartsWith()
を使います。
var aNames = characters.Where(c => c.Name.StartsWith("A")).ToList();
このように、LINQを使うと、特定の条件に合ったデータを簡単に抽出できます。
まとめ
- LINQはリストや配列を簡潔に操作できる強力な機能!
Where()
を使えば特定の条件に合うデータを抽出可能!OrderBy()
を使えば簡単に並び替えができる!- ループを書かずに済むので、コードがシンプル&読みやすくなる!

Unityのスクリプトを書くときに、リストのデータを処理することはよくあります。
LINQを活用すると、スクリプトがスッキリして可読性も上がるので、ぜひ使ってみてください!
4. Unityでの具体的な活用例
Unityでは、ラムダ式とLINQを活用することで、スクリプトをシンプルにしつつ、オブジェクトの管理やイベント処理を効率化できます。ここでは、具体的なコード例を交えながら、その実用的な活用方法を紹介します。
① ゲームオブジェクトのフィルタリング
ゲームオブジェクトのリストから、特定の条件に合うものだけを抽出する場合、Where()
を使うとシンプルに記述できます。
例:HPが50以上の敵だけを抽出
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
var strongEnemies = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
// 結果を表示
foreach (var enemy in strongEnemies)
{
Debug.Log(enemy.name + " はHP50以上の強敵です!");
}
このコードでは、タグが “Enemy” のオブジェクトをすべて取得し、その中から HP > 50
のものだけをリスト化しています。Where()
を使うことで、簡潔に条件付きの検索が可能になります。
② ボタンのクリック処理をシンプルに
UnityのUIボタンにイベントを登録する際、ラムダ式を使うと、スクリプトの可読性が向上します。
例:ボタンが押されたときにログを表示
using UnityEngine;
using UnityEngine.UI;
public class ButtonExample : MonoBehaviour
{
public Button button;
void Start()
{
button.onClick.AddListener(() => Debug.Log("ボタンが押されました!"));
}
}
通常、イベントハンドラーを別のメソッドで定義することが多いですが、ラムダ式を使えば短く記述できます。処理がシンプルな場合は、特に有効です。
③ ゲームオブジェクトのソート
LINQの OrderBy()
を使うと、特定のパラメータに基づいてリストを並び替えることができます。
例:キャラクターをレベル順にソート
using System.Linq;
using UnityEngine;
using System.Collections.Generic;
public class CharacterSorter : MonoBehaviour
{
class Character
{
public string Name;
public int Level;
public Character(string name, int level)
{
Name = name;
Level = level;
}
}
void Start()
{
List<Character> characters = new List<Character>
{
new Character("勇者", 10),
new Character("魔法使い", 5),
new Character("戦士", 8)
};
var sortedCharacters = characters.OrderBy(c => c.Level).ToList();
foreach (var character in sortedCharacters)
{
Debug.Log($"{character.Name}(レベル: {character.Level})");
}
}
}
このスクリプトでは、OrderBy()
を使ってキャラクターリストをレベル順に並び替えています。複数のオブジェクトを扱う際にとても便利です。
④ オブジェクトの一括処理
複数のオブジェクトに一括で処理を適用する際にも、ForEach()
を使うと簡潔になります。
例:すべての敵オブジェクトを非アクティブにする
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
enemies.ToList().ForEach(enemy => enemy.SetActive(false));
このコードでは、ToList()
で配列をリスト化し、ForEach()
を使ってすべての敵オブジェクトを非アクティブにしています。
⑤ 配列のデータを変換
Select()
を使うと、特定のデータを取り出したり、変換したりすることができます。
例:敵オブジェクトの名前だけを取得
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
var enemyNames = enemies.Select(e => e.name).ToList();
enemyNames.ForEach(name => Debug.Log("敵の名前: " + name));
このコードでは、敵オブジェクトの名前だけをリストにして、ログに出力しています。データの抽出や変換に便利です。

ラムダ式とLINQを使うことで、Unityのスクリプトをシンプルかつ効率的に記述できます。特に、オブジェクトのフィルタリングやソート、一括処理などで役立ちます。ただし、複雑な処理になりすぎると可読性が下がるため、適切に活用しましょう!
5. ラムダ式とLINQを使う際の注意点
ラムダ式とLINQはとても便利ですが、使い方を間違えるとUnityのパフォーマンスに悪影響を与えたり、スクリプトが読みにくくなったりすることがあります。ここでは、よくある注意点を紹介します。
① 処理負荷に注意
LINQはリストや配列を簡単に操作できるため便利ですが、Where
や OrderBy
などのクエリは内部的にループ処理を行っています。
そのため、大量のオブジェクトやデータを処理すると、フレームレートが落ちる原因になります。
❌ 避けるべきコード(毎フレーム実行すると重い)
void Update()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
var strongEnemies = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
}
このコードでは、毎フレーム FindGameObjectsWithTag
を実行し、さらに Where
でフィルタリングしているため、パフォーマンスに悪影響を及ぼします。
✅ 改善例(事前にリストを作成する)
List<GameObject> enemies;
void Start()
{
enemies = GameObject.FindGameObjectsWithTag("Enemy").ToList();
}
void Update()
{
var strongEnemies = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
}
敵リストを Start()
で一度だけ取得し、必要に応じてリストを更新するようにすると、負荷を減らせます。
② 可読性の低下に注意
ラムダ式は短く書けるため便利ですが、複雑な処理を1行に詰め込むと可読性が下がります。
特に、ネスト(入れ子)されたラムダ式は非常に読みにくくなるので注意しましょう。
❌ 避けるべきコード(複雑すぎるラムダ式)
var result = enemies.Where(e => e.GetComponent<Enemy>().HP > 50)
.OrderBy(e => e.GetComponent<Enemy>().Speed)
.Select(e => e.GetComponent<Enemy>().Name).ToList();
このコードは一見スマートに見えますが、GetComponent<Enemy>()
を何度も呼び出していて、処理も見づらくなっています。
✅ 改善例(適切に分解して記述)
var enemyList = enemies.Select(e => e.GetComponent<Enemy>()).ToList();
var strongEnemies = enemyList.Where(e => e.HP > 50);
var sortedEnemies = strongEnemies.OrderBy(e => e.Speed);
var enemyNames = sortedEnemies.Select(e => e.Name).ToList();
分解すると可読性が上がり、デバッグもしやすくなります。
③ デバッグが難しくなる
ラムダ式を多用すると、エラー発生時にデバッグがしづらくなることがあります。
特に NullReferenceException
(ヌル参照エラー)が起こると、どこでエラーが発生したのか分かりにくくなります。
❌ デバッグしにくいコード
var result = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
このコードで GetComponent<Enemy>()
が null
の場合、エラーが発生しますが、どのオブジェクトでエラーが起こったのか特定しにくいです。
✅ 改善例(デバッグしやすい書き方)
foreach (var e in enemies)
{
var enemy = e.GetComponent<Enemy>();
if (enemy != null && enemy.HP > 50)
{
Debug.Log($"強い敵: {enemy.Name}");
}
}
このように書くと、デバッグ時に Debug.Log()
でどのオブジェクトが処理されているか確認でき、エラーの原因を特定しやすくなります。
④ ToList() を乱用しない
LINQを使うとき、ToList()
を多用すると不要なリストコピーが発生し、メモリの無駄遣いにつながります。
❌ 避けるべきコード
var filteredList = enemies.Where(e => e.GetComponent<Enemy>().HP > 50).ToList();
var sortedList = filteredList.OrderBy(e => e.GetComponent<Enemy>().Speed).ToList();
ToList()
を何度も使うと、リストがその都度新しく作られ、メモリの負担が増えます。
✅ 改善例
var filteredAndSortedEnemies = enemies.Where(e => e.GetComponent<Enemy>().HP > 50)
.OrderBy(e => e.GetComponent<Enemy>().Speed);
IEnumerable<T>
のまま処理を続ければ、無駄なリストコピーを防ぐことができます。
⑤ Find() や FindAll() の方が速い場合がある
LINQの Where()
は柔軟にフィルタリングできますが、List<T>.Find()
や FindAll()
の方が高速な場合があります。
❌ LINQを使った場合
var foundEnemy = enemies.FirstOrDefault(e => e.GetComponent<Enemy>().HP > 50);
この方法でも探せますが、FirstOrDefault()
は Where()
と組み合わせて使うより、専用メソッドの Find()
の方が速いことがあります。
✅ Find()
を使う例
var foundEnemy = enemies.ToList().Find(e => e.GetComponent<Enemy>().HP > 50);
Find()
はリストの中から最初に条件を満たす要素を探すため、全件チェックする Where().FirstOrDefault()
より高速に動作します。
まとめ
- LINQの多用はパフォーマンスに影響する → 毎フレームの処理には向かない
- 可読性を意識する → 無理に1行で書かず、適切に分割する
- デバッグしやすいコードを書く →
Debug.Log()
を活用し、問題を特定しやすくする - 不要な
ToList()
を減らす →IEnumerable<T>
のまま処理を進める - 場合によっては
Find()
の方が速い → シンプルな検索には専用メソッドを活用

ラムダ式とLINQは強力なツールですが、適切に使わないと逆効果になってしまいます。これらの注意点を意識しながら、Unity開発をスムーズに進めましょう!
6. まとめ
ラムダ式とLINQを活用すると、UnityのC#スクリプトをシンプルに書けて、より直感的なコードを書くことができます。特に、オブジェクトのフィルタリングやイベント処理、データのソートなどに役立ちます。
しかし、使い方を誤るとパフォーマンスの低下やデバッグの難易度が上がることもあるため、以下の点に注意しましょう。
✅ ラムダ式を使いすぎない
ラムダ式は短縮記法として非常に便利ですが、複雑な処理をラムダ式だけで書こうとすると可読性が下がります。コードが長くなりそうな場合は、通常のメソッドを定義して使う方が良いでしょう。
✅ LINQの処理負荷を考慮する
LINQのWhere
やOrderBy
などのメソッドは強力ですが、大量のオブジェクトに適用すると処理負荷が高くなります。特に、ToList()
を繰り返し使うと不要なオブジェクト生成が発生し、メモリ使用量が増えてしまうので注意が必要です。
✅ パフォーマンスが重要な場面ではforループも活用する
LINQは記述の簡潔さでは優れていますが、速度面ではfor
ループの方が速いことがあります。リアルタイム処理が求められる場面では、適切に使い分けることが大切です。
ラムダ式とLINQを適切に活用することで、より効率的なUnity開発が可能になります。今回紹介したサンプルコードを試しながら、自分のプロジェクトに合った最適な使い方を見つけてみましょう!
よくある質問(FAQ)
- Qラムダ式と普通の関数の違いは何ですか?
- A
ラムダ式は短縮記法として使えるが、複雑な処理には通常のメソッドを使う方がよい。
- QLINQのWhereやOrderByはどんな場面で使うべきですか?
- A
配列やリストから特定のデータを抽出・並び替えしたいときに便利。
- Qパフォーマンスが気になる場合の対策は?
- A
ToList()
を多用しない、適切なデータ構造を選択する、キャッシュを活用する。