質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

2回答

2348閲覧

コルーチンの使い方をいまいち理解できません。

MOTOMUR

総合スコア195

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/06/07 13:27

https://qiita.com/azumagoro/items/0ff1c14e1fed4f5824ae

【Unity】ポケモンのようなターン制ゲームを作ってみた 〜ターン終了時の処理〜

上記の記事を見て、自分の作りたいターン制のRPGゲームの戦闘シーン(ドラ〇エだと思ってもらえれば)に使えそうだなと思って、いざ自分で使ってみようと思ったときに、
コルーチンの特性を理解できていないなということに気づきました。

「Unity コルーチン」で検索すると、使い方とか、基本とかの記事はいっぱいあるんですけど、どうもいまいち使い方が理解できません。

調べてわかったこと

コルーチンにすると非同期処理になる。
非同期処理なのになぜか、ターン制のゲームなどを作るのには最適と書いてある。

待ち時間を yield return new WaitForSeconds(止めたい秒数);と指定できる。
(待ち時間を前の処理が終わったらとかはどうするんだろう)

コルーチンに入ったときUpdate()の次の処理はコルーチンおわるまで始まらない。

知りたいこと。

・なぜ非同期処理になってしまうのにターン制のゲームを作るのに向いているのか。(戦闘の処理だけなら順番に処理をしていくので同期処理のほうがいいじゃないか。)

・「コルーチン⓵の中にコルーチン➁いれてコルーチン➁おわったら⓵も終わり」ってするにはどうしたらいいんだろう。
(コルーチンの終了を受け取って⓵に返せれば出来ると思うけど、やり方が載っていない。(コルーチンじゃなくてほかにある?))

・Update()内にコルーチン⓵、➁、➂を処理してねって順番に書くと⓵、➁、➂の順番は同期されてる?非同期?(非同期処理になるっていうのはコルーチンの中?コルーチンの実行の命令?どっちも??)

上記3点がどうしても調べてもわからなかったので教えてください。ggrksな内容であれば検索のヒントやURLでも構いません。自力でできるところまでは検索しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

僕もRPGを作るときはコルーチンでターンを回しています。
単に演出待ち時間などの制御がやりやすいからで、

コルーチンの特性
1.非同期処理が出来る
2.一定時間処理を止められる

のうち、2のほうだけ使っている、ということです。
参考サイトのほうにも、非同期処理とは書いておらず、処理を止められるという風にかいてますね。

コルーチンで書くと、大きな流れが上から順に追うことが出来て読みやすいので、よく使います。

ちなみに、
・コルーチンに入ったときUpdate()の次の処理はコルーチンおわるまで始まらない。
これは間違いですね。Update()と、コルーチンは非同期でどちらも動いています。

・Update()内にコルーチン⓵、➁、➂を処理してねって順番に書くと⓵、➁、➂の順番は同期されてる?非同期?(非同期処理になるっていうのはコルーチンの中?コルーチンの実行の命令?どっちも??)

⓵、➁、➂は非同期で動きます。例えば➁が止まっていても⓵と➂は動いています。

ただ、Update()で毎フレーム、コルーチンを呼び続けると大量の非同期処理が走るので、
「ボタンを押したとき」などに1回コルーチンを呼ぶのがいいですね。

投稿2020/06/09 04:07

ganta7188

総合スコア436

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

リンク先を見てみましたが、謎ですね。そもそも「非同期処理」の意味を理解していない印象を受けました。

非同期処理は、通常は複数の処理を並列に行いたい時に行います。常に1つの処理しか行わないのであれば、非同期処理はプログラミングが面倒になるだけですので使わないのが一般的です。
複数の処理を「順番」に行うだけで、他の何らかの処理を並行して処理する必要がない場合は、普通は同期処理で行います。

重要なのは、各処理は行われる場合と行われない場合があり、処理が行われる場合には、「順番に」エフェクトやUI表示を行う必要があるということです。

の流れから非同期処理を導いていますので、恐らく理解できていません。

さて、コルーチンですが、これは複数の処理を並行して行いたい時に使います。
処理がA, B, C, Dと4つほど有り、A→{B, C}→D(BとCは並行に処理する)のように「順番」に行う処理と「並行」して行う処理が入り混じっているような時にコルーチンは便利です。

もちろん、普通にスレッドで処理してもよいのですが、スレッドは排他制御がかなり厄介なのでコルーチンで十分(マルチコア処理を行う必要がない等)な時はコルーチンで組んでおくとバグが発生しにくくなります。
他にステートマシンで処理することもできますが、「順番」に行う処理をステートマシンで記述するのは手間がかかりバグを生みやすいです。

「コルーチン⓵の中にコルーチン➁いれてコルーチン➁おわったら⓵も終わり」ってするにはどうしたらいいんだろう。

コルーチン①とコルーチン②を合体したコルーチン③を作るか、コルーチン①の中からコルーチン②を起動し、コルーチン①の最後でコルーチン②の終了を待ちます。
しかし、.NETのC#のコルーチンは残念ならが、コルーチンの中からコルーチンを呼び出せない制限の強いコルーチンです。もし、お使いのUnityが.NETのC#を使っているならできないと思います。

コルーチンには、スタックフルとスタックレスの2種類あります。
スタックフルなコルーチンはコルーチンを呼び出した時、コルーチン毎に割り当てられるスタックに戻り番地を積めるから戻ってこれます。
しかし、スタックレスなコルーチンは、全てのコルーチンで1つのスタックを共有する関係上、他のコルーチンからの戻り番地を記録する術がないため、他のコルーチンを呼び出すことはできません。

もし、お使いのUnityがスタックフルなコルーチンをサポートしていたら、普通にコルーチン起動手順を踏んでコルーチン②を起動すれば(呼び出せば)よいはずです。(本家C#がサポートしていないので無理っぽい気もます。)

投稿2020/06/07 14:04

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sakura_hana

2020/06/08 00:31

横から失礼します。 「コルーチン①の中にコルーチン②いれてコルーチン②おわったら①も終わり」について、以下のような形で動作可能です。 IEnumerator Cor1() { yield return Cor2(); // この下はCor2が終わるまで実行されない } IEnumerator Cor2() { yield return new WaitForSeconds(2); }
Chironian

2020/06/08 05:30 編集

sakura_hanaさん なるほどです。コルーチン①と②を「順番」に実行することは可能なのですね! 並列処理しなければ問題ないはずですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問