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

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

ただいまの
回答率

90.98%

  • C#

    5794questions

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

  • Unity

    3042questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

StartCoroutineで呼び出せない。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 170

YukioMaki

score 8

UnityでC#を使って作っています。
コールチンを使ってsound Play();を30秒ごとに実行させたいのですが、StartCoroutine(Sleep));からIEnumerator Sleep()に移行しません。
そのためにaddText textの表示が 1 、30秒後に 2 を表示したいのですが、すぐに 2 を表示してしまいます。
また、このスクリプトで 1 、30秒後に 2 を表示出来るのかも分からないので訂正箇所を教えてもらえますか。 
下記にそのスクリプトを添えて置きます。
・・・・
void Update()
{
ST = GameObject.Find("Stage");
scripta1 = ST.GetComponent<Stage2>();
T = scripta1.total;
if (Input.anyKey)
{
if (T < 0)
StartCoroutine(Sleep());

{
addText.text = " " + 1.ToString();
sound.PlayWide();
Debug.Log("add");
}
if (T < 1)
StartCoroutine(Sleep());

{
addText.text = " " + 2.ToString();
sound.PlayWide();
Debug.Log("add");
}
}
}
IEnumerator Sleep()
{
yield return new WaitForSeconds(30.f);
}
}
*T=5と考えてください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

StartCoroutine(実行したい内容) は、実行したい内容を「やっておいてね!」と言って、すぐ次の行に進んでしまうので、質問のような挙動になります。

また、すぐに次の行に進んでしまうので、複数回StartCoroutine()で待つ処理を呼び出しても、何回か連続して待つ(30秒待ったあとに、さらに30秒待つ)という処理にはなりません。

質問にある仕様を正しく理解できているか分かりませんが、

  1. 「1」を表示する
  2. 30秒待つ
  3. 「2」を表示する
  4. 30秒待つ
    ・・・

というような挙動を期待している場合は、StartCoroutine()で呼び出すSleep()側で、WaitForSeconds()とaddText.text = " " + 1.ToString();・・・のループを処理する必要があるかと思います。
また、引数としてループ回数などを渡す必要もあるかと思います。

Unity スクリプトリファレンス MonoBehaviour.StartCoroutine
https://docs.unity3d.com/jp/540/ScriptReference/MonoBehaviour.StartCoroutine.html
にあるサンプルを参考にするとよいかと思います。


追記:
質問にあるコード(抜粋)を読みやすく(バグを仕込みにくく)書き直してみると、次のようになっているかと思います。
不等号の向きなどが期待している動作と異なっているような気がしますので、一旦見直してみては?

if (T < 0)
{
    StartCoroutine(Sleep()); 
}
addText.text = " " + 1.ToString();

if (T < 1)
{
    StartCoroutine(Sleep()); 
}
addText.text = " " + 2.ToString();

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/15 15:33

    toris-birdsさん回答ありがとうございます。
    書かれていたサンプルを参考に下記のスクリプトに書き換えたところ、[ 'void' は反復子インターフェイス型ではないため、'Addsistem.Update()' の本体は反復子ブロックにできません。]エラーになりました。
    訂正を教えていただきたいのですが、
    ・・・
    void Start()
    {
    addText.text = " ";
    sound = GameObject.Find("SoundManager").GetComponent<SoundManager>();


    }

    void Update()
    {
    ST = GameObject.Find("Stage");
    scripta1 = ST.GetComponent<Stage2>();
    T = scripta1.total;

    if (Input.anyKey)
    {
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");

    if (T < 0)
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }
    if(T<1)
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }

    }
    }
    IEnumerator DoSomething(float someParamerter)
    {
    while (true)
    {
    print("DoSomething Loop");
    yield return null;
    }
    }
    }
    void Start()
    {
    addText.text = " ";
    sound = GameObject.Find("SoundManager").GetComponent<SoundManager>();


    }

    void Update()
    {
    ST = GameObject.Find("Stage");
    scripta1 = ST.GetComponent<Stage2>();
    T = scripta1.total;

    if (Input.anyKey)
    {
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");

    if (T < 0)
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }
    if(T<1)
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }

    }
    }
    IEnumerator DoSomething(float someParamerter)
    {
    while (true)
    {
    print("DoSomething Loop");
    yield return null;
    }
    }
    }
    void Start()
    {
    addText.text = " ";
    sound = GameObject.Find("SoundManager").GetComponent<SoundManager>();


    }

    void Update()
    {
    ST = GameObject.Find("Stage");
    scripta1 = ST.GetComponent<Stage2>();
    T = scripta1.total;

    if (Input.anyKey)
    {
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");

    if (T < 0)
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }
    if(T<1)
    StartCoroutine("DoSomething", 2.0f);
    yield return new WaitForSeconds(1);
    StopCoroutine("DoSomething");
    {
    addText.text = " " + 1.ToString();
    sound.PlayWide();
    }

    }
    }
    IEnumerator DoSomething(float someParamerter)
    {
    while (true)
    {
    print("DoSomething Loop");
    yield return null;
    }
    }
    }

    キャンセル

  • 2017/11/15 16:39 編集

    YukioMakiさん

    まず、質問やコメントは、Markdownを使ってフォーマットしましょう。
    インデントも抜けているので、非常に読みにくいです。
    また、同一のコードが繰り返しペーストされているようです。
    投稿、コメント後には、一度内容を見直しましょう。
    ・・・と思ったら、コメント欄は、Markdownがうまく動作しないみたいですね。

    ざっくり打ち直しておきました。質問にあるコードと若干仕様が変わっているかもしれません。
    (最初の「1」を一定時間待った後に出す仕様になっています。)
    また、動作確認、コンパイル等通していないので、typo等あるかもしれませんが、ご容赦を。

    ----

    ```c#
    void Start()
    {
    addText.text = " ";
    sound = GameObject.Find("SoundManager").GetComponent<SoundManager>();
    }

    void Update()
    {
    ST = GameObject.Find("Stage");
    scripta1 = ST.GetComponent<Stage2>();
    T = scripta1.total;

    if (Input.anyKey)
    {
    StartCoroutine(DoSomething(T));
    }
    }

    IEnumerator DoSomething(int T)
    {
    for (int i = 0; i < T; i++)
    {
    yield return new WaitForSeconds(1); // 指定時間待つ
    String text = String.format(" {0}", i); // " " + i.ToString(); でも作れると思いますが・・
    print(text);
    sound.PlayWide();

    // (UIスレッドとは別のスレッドで動作するはずなので)ここで呼ぶと例外が発生するかと思います。
    // 必要な場合は、別途。
    // addText.text = text;
    }
    }
    ```

    キャンセル

  • 2017/11/18 23:58

    toris-birdsさんコードを書き直し構想どうりに動くようになりました。
    ありがとうございます。
    また、ご指導よろしくお願いします。

    キャンセル

  • 2017/11/20 12:51 編集

    @YukioMaki さん
    動くようになったようで、よかったです。
    今回の質問の範囲からは外れますが、Update()は、設定したフレームレート(例えば60FPS)などに応じて、1秒間に数10回呼び出されるかと思います。また、キーは押してすぐ手を離したとしても、0.1秒程度は押したままになっているかと思います。

    なので、Update()の中でキー入力に応じて呼ばれる処理は、1回のキー入力でかなりの回数呼ばれることになるかと思います。(似たようなタイミングで同じ処理が走るので、表示上は問題なさそうに見えるかもしれません。) 実装に慣れて来たら、その当たりを考慮して設計を変えた方がよいかと思います。

    参考になれば。

    キャンセル

0

サウンドのPlayと30秒待つをコルーチン内で行えばできると思います。

IEnumerator SoundLoop()
{
    while(true)
    {
        // サウンド再生
        sound.PlayWide();

        // 30秒待つ
        yield return new WaitForSeconds(30.f);
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/12 14:41 編集

    おそらく、質問者が想定している動作は、yield return new WaitForSeconds(30.f); sound.PlayWide(); の順かと思います。

    キャンセル

  • 2017/11/15 15:25 編集

    StudioAresさん回答ありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    5794questions

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

  • Unity

    3042questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。