「HPが0になったらゲームオーバー」「敵を5体出す」など、ゲームは「〜なら」と「くり返し」でできています。今回はプログラムの流れを変えるif文と、同じ処理をくり返すfor文・while文・foreach文、そしてたくさんのデータをまとめて扱う配列をご紹介します!
この記事で学べること
- if文を使った条件分岐
- 比較演算子と論理演算子
- for文・while文を使った繰り返し処理
- 配列とforeach文で、たくさんのデータをまとめて扱う方法
前提知識
- 変数でデータを保存しよう:変数の使い方
この記事のサンプルは、どれもStartの中に書いて再生し、Consoleで結果を見る形で試せます。6-4と同じように、空のゲームオブジェクトにスクリプトをアタッチして試してみてください。
if文で条件分岐
基本的なif文
条件を満たしたときだけ処理を実行するには、if文を使います:
int score = 70;
if (score >= 60)
{
Debug.Log("合格です!");
}
if文の構造:
if (条件)
{
条件がtrue(はい)のときだけ実行される処理
}
if-else文:どちらか一方
条件によって、2つのうちどちらかを実行する場合:
int score = 75;
if (score >= 80)
{
Debug.Log("素晴らしい!");
}
else
{
Debug.Log("もう少し頑張りましょう");
}
else if:3つ以上の分かれ道
int score = 85;
if (score >= 90)
{
Debug.Log("Sランク!");
}
else if (score >= 80)
{
Debug.Log("Aランク!");
}
else if (score >= 70)
{
Debug.Log("Bランク!");
}
else
{
Debug.Log("がんばりましょう");
}
上から順番に調べて、最初に当てはまったところだけが実行されます。85点は「90以上」には当てはまらず、「80以上」に当てはまるので「Aランク!」になります。
boolはそのまま条件に使える
6-4で紹介したbool型は、そのままifの条件に書けます:
bool isGameOver = true;
if (isGameOver)
{
Debug.Log("ゲームオーバー");
}
比較演算子
条件の中で使う、主な比較演算子です:
| 演算子 | 意味 | 例 |
|---|---|---|
== | 等しい | score == 100 |
!= | 等しくない | score != 0 |
> | より大きい | score > 80 |
< | より小さい | score < 60 |
>= | 以上 | score >= 80 |
<= | 以下 | score <= 60 |
注意:=(代入)と==(比べる)は別物です!
論理演算子
いくつかの条件を組み合わせる場合:
int score = 85;
bool hasBonus = true;
// AND:両方ともtrueのとき
if (score >= 80 && hasBonus)
{
Debug.Log("ボーナスポイントゲット!");
}
// OR:どちらか一方でもtrueのとき
if (score >= 90 || hasBonus)
{
Debug.Log("特別賞!");
}
// NOT:true/falseを反対にする
if (!hasBonus)
{
Debug.Log("ボーナスなし");
}
&&:AND(かつ)||:OR(または)!:NOT(〜でない)
for文で決まった回数くり返す
基本的なfor文
for (int i = 0; i < 5; i++)
{
Debug.Log("カウント: " + i);
}
実行結果:
カウント: 0
カウント: 1
カウント: 2
カウント: 3
カウント: 4
for文の構造:
for (最初に1回やること; くり返す条件; 1回ごとにやること)
{
くり返す処理
}
int i = 0:カウンター用の変数iを0から始めるi < 5:iが5より小さい間くり返すi++:1回終わるごとにiを1増やす(i = i + 1と同じ)
0から数えて「5より小さい間」なので、0〜4の5回実行されます。
while文で条件を満たす間くり返す
基本的なwhile文
int hp = 30;
int damage = 8;
int turn = 0;
while (hp > 0)
{
hp -= damage;
turn++;
Debug.Log(turn + "ターン目:残りHP " + hp);
}
Debug.Log(turn + "ターンで倒した!");
実行結果:
1ターン目:残りHP 22
2ターン目:残りHP 14
3ターン目:残りHP 6
4ターン目:残りHP -2
4ターンで倒した!
何回くり返すか最初からは分からないけど、「HPが0より大きい間」のように条件で止めたいときはwhile文を使います。
注意:条件がずっとtrueのままだと、無限ループになってUnityが固まります!
// 危険:hpを減らし忘れていて、永遠に終わらない
while (hp > 0)
{
Debug.Log("止まらない!");
}
5-1の記事で説明したとおり、固まったUnityは強制終了するしかありません。whileを書くときは、くり返しの中で条件が変わるかを必ず確認しましょう(再生前のCtrl+Sもお忘れなく)。
配列とforeach文:たくさんのデータをまとめて扱う
配列とは
同じ型のデータを、番号付きでまとめて入れておく箱です。
string[] enemyNames = { "スライム", "ゴブリン", "ドラゴン" };
Debug.Log(enemyNames[0]); // スライム(番号は0から始まる)
Debug.Log(enemyNames[2]); // ドラゴン
Debug.Log(enemyNames.Length); // 3(入っている数)
型[]で配列になる- 番号(インデックス)は0から始まる。3つ入っている配列の最後は
[2] - 存在しない番号(
[3]など)を使うと、5-3の記事で紹介したIndexOutOfRangeExceptionになります
Inspectorで配列を設定する
[SerializeField]を付けると、配列もInspectorで中身を設定できます:
[SerializeField] private int[] stageScores = { 100, 250, 400 };
Inspectorに「Stage Scores」の欄が出て、+ボタンで数を増やしたり、値を書き換えたりできます。
foreach文で全部を順番に取り出す
string[] enemyNames = { "スライム", "ゴブリン", "ドラゴン" };
foreach (string enemyName in enemyNames)
{
Debug.Log(enemyName + "があらわれた!");
}
配列の中身を、最初から最後まで1つずつ取り出してくり返します。番号を気にしなくていいので、「全部に同じことをする」ときはforeachが便利です。
実践サンプル:ステージの結果を判定する
今までの内容を組み合わせてみましょう。Inspectorでステージごとのスコアを設定しておき、合計と評価をConsoleに表示します。
using UnityEngine;
public class StageResult : MonoBehaviour
{
[SerializeField] private int[] stageScores = { 80, 95, 60 };
[SerializeField] private int clearLine = 70;
void Start()
{
int total = 0;
int clearCount = 0;
// 全ステージのスコアを順番に調べる
for (int i = 0; i < stageScores.Length; i++)
{
int score = stageScores[i];
total += score;
if (score >= clearLine)
{
clearCount++;
Debug.Log("ステージ" + (i + 1) + ":" + score + "点 クリア!");
}
else
{
Debug.Log("ステージ" + (i + 1) + ":" + score + "点 もう一息");
}
}
// 最後に全体の評価
if (clearCount == stageScores.Length)
{
Debug.Log("全ステージクリア!合計 " + total + "点");
}
else
{
Debug.Log(clearCount + "ステージクリア。合計 " + total + "点");
}
}
}
このサンプルのポイント:
- 配列:ステージのスコアをまとめてInspectorで設定出来る
- for文:何番目のステージかを表示したいので、番号付きでくり返す
- if-else:クリアラインを超えたかどうかでメッセージを変える
- InspectorでStage ScoresやClear Lineの値を変えて再生し直すと、結果が変わります
注意点やヒント
インデント(字下げ)をそろえましょう
{ }の中は1段下げて書くと、どこからどこまでがifの中なのかが一目で分かります。VS CodeでShift+Alt+F(Macの場合はShift+Option+F)を押すと、自動で整えてくれます。
長い条件は変数に分ける
// 読みにくい例
if (score >= 90 && hp > 0 && !isGameOver)
{
Debug.Log("ハイスコアで生き残った!");
}
// 読みやすい例:条件に名前を付ける
bool isHighScore = score >= 90;
bool isAlive = hp > 0 && !isGameOver;
if (isHighScore && isAlive)
{
Debug.Log("ハイスコアで生き残った!");
}
スライムif文の中にif文を書いて、さらにその中に・・・と深くなりすぎて迷子になった・・・



入れ子は2段ぐらいまでを目安にしよう!深くなってきたら、次の6-6で覚える「メソッド」に分けるとスッキリするよ
よくあるエラーと対処法
エラー:無限ループでUnityが固まった
- 原因:while文の条件が、ずっとtrueのまま変わらない
- 対処法:Unityを強制終了して、くり返しの中で条件の変数を更新しているか確認する
エラー:ifの条件が思った通りに動かない
- 原因:
=(代入)と==(比較)を間違えている。またはelse ifの順番が違う(上から順に調べるので、>= 70を>= 90より先に書くと、90点でもBランクになる) - 対処法:比較は
==。範囲のチェックは、厳しい条件から順に書く
エラー:IndexOutOfRangeException
- 原因:配列の存在しない番号を使った(例:3つの配列で
[3]) - 対処法:番号は0から始まることを思い出す。forの条件は
i < 配列.Lengthにする
エラー:論理演算子の組み合わせで結果がおかしい
- 原因:
&&と||を混ぜたときの順番 - 対処法:迷ったらカッコでくくる:
if ((a && b) || c)
まとめ
- if文:条件によって処理を分ける(else if は上から順に調べる)
- 比較演算子:
==,!=,<,>,<=,>= - 論理演算子:
&&(AND),||(OR),!(NOT) - for文:決まった回数くり返す
- while文:条件を満たす間くり返す(無限ループに注意)
- 配列とforeach:たくさんのデータをまとめて扱う
次のステップ
処理が長くなってきたら、まとまりごとに名前を付けて分けましょう。次は自分で「メソッド」を作る方法です:
コメント