回答編集履歴

3

誤記訂正

2017/12/03 15:43

投稿

KSwordOfHaste
KSwordOfHaste

スコア18392

test CHANGED
@@ -152,7 +152,7 @@
152
152
 
153
153
  ```
154
154
 
155
- (1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartにきましたが、なんども繰り返しGAを実行したいなら、適当なタイミングで(Startメソッド以外の場所で)
155
+ (1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartにきましたが、なんども繰り返しGAを実行したいなら、適当なタイミングで(Startメソッド以外の場所で)
156
156
 
157
157
  `generator = GA().getEnumerator();`
158
158
 

2

誤記訂正

2017/12/03 15:43

投稿

KSwordOfHaste
KSwordOfHaste

スコア18392

test CHANGED
@@ -114,7 +114,11 @@
114
114
 
115
115
  ---
116
116
 
117
- 補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。IEnumerable<T>というのはT型のデータを列挙するものとして捉えてください。(これはUnityの仕様ではなくC#の標準ライブラリーの仕様です)
117
+ 補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。
118
+
119
+
120
+
121
+ IEnumerator<T>はT型の要素を列挙する能力を持つ型です。(foreachなどを使うとこの型を直接目にしないため見慣れないかも知れません)。またIEnumerable<T>というのはIEnumerator<T>を生成する能力がある型で大抵のコレクション型(配列, List, Dictionaryなど)はこのインターフェースを備えています。(これはUnityの仕様ではなくC#の標準ライブラリーの仕様です)
118
122
 
119
123
 
120
124
 

1

補足

2017/12/03 07:13

投稿

KSwordOfHaste
KSwordOfHaste

スコア18392

test CHANGED
@@ -109,3 +109,47 @@
109
109
 
110
110
 
111
111
  コルーチンの動きが実感できてくると「単純なループ構造で書かれた関数を、データを次々と生み出すもの(ジェネレーター)として利用できる」「独立したプログラムの流れを複数並行して動かすことができる=>スレッドを生成せずにスレッド的な動きにできる」といった応用が見えてくると思います。
112
+
113
+
114
+
115
+ ---
116
+
117
+ 補足:上のコードが少々わかりにくかったかも知れませんね。コルーチンで実装されたジェネレーターの典型的な使い方はforeachでの利用なのですが、それと対比すると理解しやすいかも知れません。IEnumerable<T>というのはT型のデータを列挙するものとして捉えてください。(これはUnityの仕様ではなくC#の標準ライブラリーの仕様です)
118
+
119
+
120
+
121
+ ```C#
122
+
123
+ IEnumerable<T> GetGenerator() { ... }
124
+
125
+
126
+
127
+ //(1) foreachで利用する方法
128
+
129
+ foreach (T element in GetGenerator()) {
130
+
131
+ ... elementに対する処理 ...
132
+
133
+ }
134
+
135
+
136
+
137
+ //(2) 上記と同じことを別の書き方で書くと
138
+
139
+ IEnumerator<T> enumerator = GetGenerator().getEnumerator(); // (A)
140
+
141
+ while (enumerator.MoveNext()) { // (B)
142
+
143
+ T element = enumerator.Current;
144
+
145
+ ... elementに対する処理 ...
146
+
147
+ }
148
+
149
+ ```
150
+
151
+ (1)が典型的な使い方ですが、これではUpdateの1回の呼び出しで1世代のみを取り出すことができません。そこで(2)の方法に着目します。(2)なら「まだ次の要素があるかをMoveNext()で調べ、もしあるならその要素をCurrentでアクセスする」というのをUpdateの中で1回だけ行えます。(A)はIEnumerableの計算を開始するためのコードのため上の例ではStartに起きましたが、なんども繰り返しGAを実行したいなら、適当なタイミングで(Startメソッド以外の場所で)
152
+
153
+ `generator = GA().getEnumerator();`
154
+
155
+ とすれば何度でも新たな列挙をやりなおせます。