今回の記事では繰り返し処理についてみていきます。
アプリ開発ではたくさんのデータに対して同じ処理を行いたい時があるのですが、その時に繰り返し処理を利用することになります。
前回の条件分岐の制御文と併せてプログラミングの超重要ポイントの一つです。
前回の記事:
繰り返し処理(ループ、Loop)の制御文について
繰り返し処理(ループ、Loop)の制御文には次のものがあります。
- while文
- do while文
- for文
- foreach文
また、C#では次の補助的なキーワードも用意されています。
- break
- continue
while文とは
while
文は最も単純な繰り返し処理になります。
while(<条件式>) { ... }
条件式には繰り返し処理の終了判定を比較演算子などを使用して書いてください。
while
文は条件式がtrue
になり続けるまで処理を繰り返し、false
になった時に終了します。
1 2 3 4 5 |
int a = 0; //aが10以上になるまで+1する while(a < 10) { ++a; } |
do while文とは
do while
文は先に処理を実行してから条件式の結果を判断するwhile
文になります。
do { ... } while(<条件式>);
こちらもwhile
文と同じで、条件式がtrue
なら繰り返し処理を続行し、false
になると終了します。
1 2 3 4 5 |
int a = 0; //aが10以上になるまで+1している do { a++; } while(a < 10); |
for文とは
for
文はテンプレート化された繰り返し処理になります。
for(<初期化>; <条件式>; <後処理>) { ... }
- 初期化:繰り返し処理が始まる時、最初に実行される処理。
- 条件式:繰り返し処理の終了判定。
- 後処理:繰り返し処理を実行した後、最後に実行される処理。
for文を実行しますと、次のような順序で処理が実行されます。
- 初期化の実行
- 条件式の判定
- 繰り返し処理本体
- 後処理の実行
- 2.に戻る
for
文でも条件式がtrue
なら繰り返し処理を続け、false
になると終了します。
for
文は主に配列(※1)の各要素に繰り返し処理を行う事を想定された作りになっています。
配列の要素を見ていく時は一般的にループカウンターと呼ばれる変数を用意し、それを繰り返し処理のたびに+1していくことが多いです。
なので、ループカウンターをfor文の初期化の中で宣言し、条件式ではループカウンターが配列の要素数より小さいか判定し、最後に実行される処理の中で+1するといった使い方がよく出てきます。
下のサンプルコードがそのような形になっています。
(※1 配列については次の記事で詳しく解説します。配列は同じ型の値の集まりを表すものになります。)
1 2 3 4 5 |
//aが10以上になるまで+1している //ここでは変数aがループカウンターの役割になっている for (int a=0; a<10; ++a) { // ここに繰り返し処理を書く } |
foreach文とは
foreach
文はSystem.IEnumerable
インターフェイスに対して繰り返し処理を行う時に利用されます(インターフェースなどわからなければひとまずこの文は無視してOKです)。
簡単に言うと、for
文をさらに読みやすくした繰り返し処理になります。
foreach(<要素の宣言> in <コレクション>) { ... }
foreach
文を実際に使用するにはまだまだ説明していないことが多くありますので、こんな繰り返し処理があるとだけ覚えていただければOKです(コレクションも今はわからなくてOK)。
実際のプログラミングではforeach
文を使った方がコーディングしやすくなっています。さらにSystem.Linq
というコレクションに対する操作セットを組み合わせるとより効果が発揮します。
C#の中では高機能なものになりますがUnityC#講座を終える頃にはぜひともマスターしてほしい機能の一つになります。
1 2 3 4 5 6 7 8 |
var list = new List<int>() { //... listの要素を設定していく }; // listのすべての要素に対して繰り返し処理を行っている foreach(var element in list) { // elementにはlistの各要素が設定されるので、それに対して処理を行っていく。 } |
繰り返し処理内を補助するキーワード
繰り返し処理の中では次のキーワードを使用することができます。これらを使うことで繰り返し処理の途中でループを中断したり、次の繰り返し処理にジャンプすることができます。
これらはC#では式として扱われています。
- break
- continue
break
break
キーワードを使用すると繰り返し処理を途中で中断することができます。
1 2 3 4 5 |
//iが3になったら、そこで繰り返し処理を中断している。 for (var i=0; i<10; ++i) { if(i == 3) break; } |
continue
continue
キーワードを使用すると現在の繰り返し処理を中断し、次の繰り返し処理へジャンプすることができます。
1 2 3 4 5 6 |
//iが偶数の時は繰り返し処理をスキップしている for (var i=0; i<10; ++i) { if((i % 2) == 0) continue; // 何か繰り返す処理 } |
【Unityで実践】 繰り返し式を使ってみよう!
ここまでC#にある繰り返し処理について解説してきました。
アプリ作成中にはfor文かforeach文を使用することが多くなります。
ホントは配列を使用すると繰り返し処理の効果が実感しやすのですが、それについては他の記事で扱います。
今回のサンプルコードではInspectorからLoopCountとAddColorを設定することで、ColorとMeshの色を自動的に設定するものになっています。
LoopCount分、AddColorをColorに足し合わせる処理になっていて、その部分にfor
文を使用しています。ただし、Colorの赤色が1以上になったらbreak
キーワードを使用しそこで繰り返し処理を中断するようにしています。
また、繰り返し処理を行う前にLoopCountの値が0以上になるようにしていますが、一般的にループ中ではループカウンターは0から始まるようになっているからです。(配列の性質に関連しています。)
ちなみに今回の処理はAddColorにLoopCountを掛けた値をColorに設定するようにしても同じことができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using UnityEngine; public class Sample : MonoBehaviour { public int LoopCount = 3; public Color Color = Color.white; public Color AddColor = Color.black; public MeshRenderer Mesh; void OnValidate() { Color = Color.black; //黒色でColorをクリアーする //一般的にループカウンターが負の数になることはないので、0以下の時は0になるようにしている if(LoopCount < 0) LoopCount = 0; //LoopCountの数だけColorにAddColorの色を加算している for (var i=0; i<LoopCount; ++i) { Color += AddColor; // 赤色が1以上になったらそこで繰り返し処理を中断する if(Color.r >= 1) break; } //Meshが設定されていたら、Meshの色を変更する if(Mesh != null) Mesh.sharedMaterial.color = Color; } } |
余談:無限ループについて
繰り返し処理を使う際に一つだけ注意してほしいことがあります。
それは、書き方によって繰り返し処理が永久に終わらなくなってしまうことです。
これをプログラミングの世界では無限ループといいます。
GUIアプリケーションのメッセージループなど、実装上意図的に無限ループになるようにすることはありますが、Unityでは基本的に無限ループを書くことはありません。
無限ループ的な処理はMoneBehaviour.Update()
やコルーチンなどで処理を作っていくことになります。
アプリ実行中に意図しない無限ループが発生すると、アプリの挙動が停止(フリーズ)したように見えます。一度そのような状態になりますとアプリを強制終了する他なくなります。
Unityでも開発途中でうっかり無限ループになってしまうコードを書いてしまうとUnityが停止してしまいます。もしそうなった時は強制終了した後に必ず無限ループになってしまった部分の修正を行ってください。
一応無限ループのサンプルを書きますが決して実行しないようにしてください。
1 2 3 4 5 6 7 8 9 |
//一番手軽な無限ループ while(true) {} //よく読まないと無限ループの原因がわからないもの // uint型は負の数を取らないので、決して0より小さくならず、 // 0の時に-1すると、uint.MaxValueと最大値に戻ってしまう。 // そのため、このfor文は無限ループになっている for (uint i=10; 0 <= i; --i) { } |
まとめ
今回の記事をまとめると次のようになります。
- 繰り返し処理は条件を満たすまで何らかの処理を繰り返し実行する時に用いる。
- 配列などのデータの集まり(コレクション)を操作する際にも使われる。
while
文は条件式がtrue
になるまで処理を繰り返す。do while
文は先に処理を実行してから処理を繰り返すかどうか判断するwhile
文。for
文は初期値、条件式、繰り返し処理の最後に行う処理をまとめて書くことができる繰り返し処理。foreach
文はSystem.IEnumerable
に対応したデータの集まり(コレクション)を全て見ることができる繰り返し処理
一つ注意点として、繰り返し処理では指定した時間処理を繰り返すといった時間を跨ぐような処理は扱えません。繰り返し処理は常に同じタイミングで処理が順に実行されます。なので、あまりに長く処理を繰り返すとアプリの実行が停止したように見えることがあります。しばらく待つとまた動くようになりますが、現在のコンピュータでは大体1万回以上の繰り返し処理は重い処理になりますので注意しましょう。
そのような場合はUnityのMonoBehaviour.Update()
やコルーチン(※)を使用してください。もちろんC#にもSystem.Time.Interval()
など似た機能はあります。
(※まだ紹介していないUnityの機能になります。System.IEnumeartor
と関係しています。)
以上になります。それでは次の記事に行ってみましょう!
次の記事:
コメント