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

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

ただいまの
回答率

87.77%

Unity)Invokeとコルーチン

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,562

score 198

音声データ順番に再生していくアプリを作っているのですが
うまくいかない部分があるので教えて下さい。

やっている事)
1、AudioAutoPlay〇〇というスクリプトを使って
Resourcesフォルダから音声ファイルを呼び出します。
2、次に呼び出した音声ファイルのlengthを取得してから
AutoVoiceスクリプトのInvokeで音声を再生します。
3、取得したlengthと間の時間を考慮してInvokeの引数に設定しています。

実際にこれでテストをするとなぜか音声が重なってしまいます。
テストしたところ、メンバ変数のaudioClipLengthをAudioAutoPlay〇〇で
取得するのですがその取得したaudioClipLengthがAutoVoiceスクリプトのInvoke
で反映されていません(audioClipLengthが0になっている)

推測ですがResourcesフォルダで呼び出したリソースからaudioClipLengthを
呼び出しているのでResourcesを呼び出すタイムラグで取得できないものと
判断しています。

質問)
対策としてIEnumeratorを使ってResourcesの取得が完了したらaudioClipLengthを
取得してAutoVoiceスクリプトに反映させる手順を作りたいのですが
返り値が使えないInvokeにIEnumeratorがらみのAudioAutoPlay〇〇を設定する方法が
考え付きません。分かる方、教えて下さい。

環境)
PC: mac
Unity2018.3.14f1
言語:C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class AudioAutoScript : MonoBehaviour
{
    #pragma warning disable 649
    [SerializeField]Entity_titlelist etitlelist;
    [SerializeField]Entity_voicelist evoicelist;

    private int phraseNum;  //再生するデータ数
    private int startPos;  //再生するデータの開始番号

    private float audiocliplength; //再生される音声の時間

    private float audioAllSeconds; //実際のインターバル時間(グロス)

    private string dataNameTitle;
    private string dataName0;
    private string dataName1;
    private string dataName2;
    private string dataName3;
    private string dataName4;

    private int indexItemNo;

      private AudioSource audioSource;
    private AudioClip audioClip;
    float firstIntervalSeconds = 2.0f;
    float intervalSeconds = 1.0f;

    // Start is called before the first frame update
    void Start()
    {
        //AudioSourceを取得する
        audioSource = gameObject.GetComponent<AudioSource>();

        int AutoFlag = PlayerPrefs.GetInt("autoflag");
        if(AutoFlag == 0){
          indexItemNo = int.Parse(PlayerPrefs.GetString("indexitemno"));
          AutoVoice();
          // StartCoroutine("AutoVoice");
          }else{
          indexItemNo = PlayerPrefs.GetInt("autocount",1);
          AutoVoice();
          // StartCoroutine("AutoVoice");
          }
    }

    // Update is called once per frame
    void Update()
    {

    }
    private void AutoVoice(){
    // private IEnumrator AutoVoice(){
        var voiceElement = evoicelist.sheets[0].list.Where(data => data.phrase_id == indexItemNo).FirstOrDefault();
        startPos = voiceElement.converse_id - 1;
        phraseNum = evoicelist.sheets[0].list.Count(data => data.phrase_id == indexItemNo);
        dataNameTitle = etitlelist.sheets[0].list[indexItemNo - 1].conversation_file;
        dataName0 = evoicelist.sheets[0].list[startPos].conversation_file;
        dataName1 = evoicelist.sheets[0].list[startPos + 1].conversation_file;
        dataName2 = evoicelist.sheets[0].list[startPos + 2].conversation_file;
        dataName3 = evoicelist.sheets[0].list[startPos + 3].conversation_file;
        dataName4 = evoicelist.sheets[0].list[startPos + 4].conversation_file;

        switch(phraseNum){
            case 2:
              Invoke("AudioAutoPlayTitle", 1.0f);
              audioAllSeconds = audiocliplength + firstIntervalSeconds + 2.0f;
              Invoke("AudioAutoPlay0",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              Invoke("AudioAutoPlay1",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              PlayerPrefs.SetFloat("audidoallseconds", audioAllSeconds);
              PlayerPrefs.Save();
              audioAllSeconds = 0.0f;
            break;
            case 3:
              Invoke("AudioAutoPlayTitle", 1.0f);
              audioAllSeconds = audiocliplength + firstIntervalSeconds;
              Invoke("AudioAutoPlay0",audioAllSeconds);
              Debug.Log("audioallseconds" + audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay1",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay2",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              audioAllSeconds = 0.0f;
            break;
            case 4:
              Invoke("AudioAutoPlayTitle", 1.0f);
              audioAllSeconds = audiocliplength + firstIntervalSeconds + 2.0f;
              Debug.Log("audioallseconds0:" + audioAllSeconds);
              Invoke("AudioAutoPlay0",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              Debug.Log("audioallseconds1:" + audioAllSeconds);
              Invoke("AudioAutoPlay1",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              Debug.Log("audioallseconds2:" + audioAllSeconds);
              Invoke("AudioAutoPlay2",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              Debug.Log("audioallseconds3:" + audioAllSeconds);
              Invoke("AudioAutoPlay3",audioAllSeconds);
              audioAllSeconds += (audiocliplength + intervalSeconds);
              Debug.Log("audioallseconds4:" + audioAllSeconds);
              // PlayerPrefs.SetFloat("audidoallseconds", audioAllSeconds);
              // PlayerPrefs.Save();
              audioAllSeconds = 0.0f;
            break;
            case 5:
              Invoke("AudioAutoPlayTitle", 1.0f);
              // audioAllSeconds = audiocliplength + firstIntervalSeconds + 2.0f;
              audioAllSeconds = audiocliplength + firstIntervalSeconds;
              Invoke("AudioAutoPlay0",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay1",audioAllSeconds);
              audioAllSeconds  = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay2",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay3",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay4",audioAllSeconds);
              audioAllSeconds = audioAllSeconds + audiocliplength + intervalSeconds;
              // PlayerPrefs.SetFloat("audidoallseconds", audioAllSeconds);
              // PlayerPrefs.Save();
              audioAllSeconds = 0.0f;
            break;
            default:
              // AudioAutoPlayTitle();
              Invoke("AudioAutoPlayTitle", 1.0f);
              audioAllSeconds = audiocliplength + firstIntervalSeconds + 2.0f;
              Invoke("AudioAutoPlay0",audioAllSeconds);
              audioAllSeconds += audiocliplength + intervalSeconds;
              Invoke("AudioAutoPlay1",audioAllSeconds);
              audioAllSeconds += audiocliplength + intervalSeconds;
              PlayerPrefs.SetFloat("audidoallseconds", audioAllSeconds);
              PlayerPrefs.Save();
              audioAllSeconds = 0.0f;
            break;
        }
    }
    void AudioAutoPlayTitle(){
                  audioClip = ResourcesAudio(dataNameTitle);
                audioSource.PlayOneShot(audioClip);
                audiocliplength = audioClip.length;
    }
    void AudioAutoPlay0(){
                audiocliplength = ResourcesAudio(dataName0).length;
                Debug.Log("audioclip0:" + audiocliplength);
                audioSource.PlayOneShot(audioClip);
    }
    void AudioAutoPlay1(){
                audiocliplength = ResourcesAudio(dataName1).length;
                Debug.Log("audioclip1:" + audiocliplength);
                audioSource.PlayOneShot(audioClip);
    }
    void AudioAutoPlay2(){
                audiocliplength = ResourcesAudio(dataName2).length;
                Debug.Log("audioclip2:" + audiocliplength);
                audioSource.PlayOneShot(audioClip);
    }
    void AudioAutoPlay3(){
                audiocliplength = ResourcesAudio(dataName3).length;
                Debug.Log("audioclip3:" + audiocliplength);
                audioSource.PlayOneShot(audioClip);
    }
    void AudioAutoPlay4(){
                audiocliplength = ResourcesAudio(dataName4).length;
                audioSource.PlayOneShot(audioClip);
    }
    AudioClip ResourcesAudio(string dataName)
    {
      audioClip = Resources.Load("Voices/" + dataName)as AudioClip;
      return audioClip;
    }


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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

void Start () {
    StartCoroutine("AutoVoice");
}
private IEnumrator AutoVoice() {
    yield return AudlioPlay(dataNameTitle);
    yield return AudlioPlay(dataName0);
    yield return AudlioPlay(dataName1);
    // 以下省略
}
private IEnumrator AudlioPlay(string fileName) {
    audioClip = ResourcesAudio(fileName);
    audioSource.PlayOneShot(audioClip);

    // (※)以下がもしかしたら必要かも(ロード・再生開始までに時間かかるかも)
    yield return null;

    // audioClip.lengthがちゃんと取れるなら以下でOK
    yield return new WaitForSeconds(audioClip.length);

    // audioClip.lengthがどうしても0になるようなら以下にしてみるとか
    while (audioSource.isPlaying) {
        yield return null;
    }
}


コルーチンを使うなら、そもそもInvokeを使う必要がありません。
yield return コルーチン;とすると、そのコルーチンが終了するまで待機します)

ただ何故audioClipLengthが0になるのか分かりません。恐らくロード時間が発生しているのだと思いますが、Debug.Log仕込んだり※部分の待ち時間を変えたりして検証してみてください。
(ちなみにyield return null;は「1フレーム」の時間に相当します)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/21 17:17

    うまくいきました。
    audioClip.lengthも0になりませんでした。
    ありがとうございます。これからもよろしくお願いします。

    キャンセル

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

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

関連した質問

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