Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

コルーチンを使おう

  • Login to see the comments

コルーチンを使おう

  1. 1. コルーチンを使おう
  2. 2. WHO AM I?• ナムアニクラウドと申します• 主にC#でゲームなどのプログラミングをしてます• Twitter: @NumAniCloud Twitterアイコン→
  3. 3. コルーチンとは// イメージ(C#)IEnumerator ShotRoutine(){ Shot(); yield return 0; // ここで抜ける! Shot(); // 続きはあとで実行する}• 関数とかメソッドの仲間です• 途中で抜けて、あとで再開することができるのが特徴です
  4. 4. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  5. 5. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  6. 6. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  7. 7. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  8. 8. 実行のイメージ// 定義 // 呼び出しIEnumerator Fiber(){ void Main(){ Shot(); var x = Fiber(); yield return 0; x.MoveNext(); Shot(); Hoge(); Shot(); x.MoveNext(); yield return 0; x.MoveNext(); yield return 0; x.MoveNext();} }
  9. 9. 例(C#)ゲームで敵キャラクターの制御をしたい • 下へ移動 void Update(){ • 2秒待つ 下へ移動; • 5回繰り返す 2秒待つ; • 弾を撃つ 5回繰り返す { • 1秒待つ 弾を撃つ; 1秒待つ; } } 理想
  10. 10. 例(C#)ゲームで敵キャラクターの制御をしたい • 下へ移動 void Update(){ • 2秒待つ 下へ移動; • 5回繰り返す 2秒待つ; • 弾を撃つ 5回繰り返す { • 1秒待つ 弾を撃つ;ここで処理を止めたいけど、 1秒待つ;この関数を抜けないと他の関数の処理ができず }ゲーム全体が止まってしまう! } 理想 現実
  11. 11. 例(C#)そこでコルーチン ここでは1秒 = 60フレームIEnumerator Update(){ 下へ移動; for( int i = 0; i < 120; ++i ) void 2秒待つ // Update(){ yield return 0; 下へ移動; for( int i = 0; i < 5; ++i ){ 2秒待つ; 弾を撃つ; 5回繰り返す for( int j = 0; j < 60; ++j ) // 1秒待つ{ yield return 0; 弾を撃つ; } 1秒待つ;} } }
  12. 12. コルーチンなしだと毎フレーム呼び出してもらうしかない ここでは1秒 = 60フレームint t = 0; カウンターが必要void Update(){ if( t == 0 ){ 下へ移動; for文も使えないので、変な条件式を書く } if( t >= 120 && ( t – 120 ) % 60 == 0 && t < 120 + 60 * 5 ){ 弾を撃つ; } ++t; 時間を絶対的に指定}
  13. 13. 使い道• RPGの戦闘シーンなど • プレイヤーの作戦が決まるまで戦闘の進行を止める • エフェクトの表示が終わるまで戦闘の進行を止める• 状態のシーケンスの管理 • 敵が歩いて登場する状態 → 攻撃する状態 → 攻撃が終わって退場する状態• 遅延評価 • 呼び出しが達するまで計算しないことで無駄を省く • 無限の量の計算を途中で打ち切る• ジェネレータ(値を列挙する)
  14. 14. 使い道:遅延評価IEnumerator Fiber(){ void Main(){ Func(); var x = Fiber(); yield return 0; x.MoveNext(); Func(); x.MoveNext(); yield return 0; } HeavyFunc(); // 実行されない yield return 0;}
  15. 15. 使い道:ジェネレータIEnumerator Fiber(){ void Main(){ yield return 3; var x = Fiber(); yield return 1; x.MoveNext(); yield return 4; x.Current; // 3 x.MoveNext(); yield return 1; x.Current; // 1 yield return 5; x.MoveNext();} x.Current; // 4 }
  16. 16. コルーチンを使える言語機能• C#のイテレータ• Luaのコルーチン• Pythonのジェネレータ• Rubyのファイバー• 東方弾幕風スクリプトのマイクロスレッド• (まだあるかも)
  17. 17. ありがとうございました

×