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

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

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

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

Unity

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

Q&A

解決済

1回答

2167閲覧

Unity スクリプトで、GUIボタンから音声を取得し、再生するやり方がうまくいかない

kazuh1r010

総合スコア23

C#

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

Unity

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

0グッド

0クリップ

投稿2018/02/14 11:58

編集2018/02/14 12:05

Unityでスクリプトを使い、アプリケーションパスにある音声ファイルを取得し、GUIのボタンで押すと再生出来る様にしたいと
考えていますが、うまくいきません。

再生するだけなら他に方法はあると思いますが、このやり方を選ぶ理由として
今回のプログラムの前に音声をマイクで取得し、保存してから、再び呼び出して音声解析まで
行えるアプリを作りたいと考えているためです。

ファイルを取得し再生するまでのコードは以下のようにしています。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class AudioRead 6{ 7 public void ReadAudio() 8 { 9 using (WWW www = new WWW("file:///" + Application.dataPath + "myvoice.wav")) 10 { 11 yield return www; 12 13 AudioClip audioTrack = www.GetAudioClip(false, true); 14 AudioSource source = gameObject.AddComponent<AudioSource>(); 15 source.clip = audioTrack; 16 source.Play(); 17 } 18 } 19}

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Start_analyze_action : MonoBehaviour 6{ 7 AudioRead audioreads; 8 // Use this for initialization 9 void Start() { } 10 // Update is called once per frame 11 void Update() { } 12 void OnGUI() 13 { 14 if (GUI.Button(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 80, 100, 50), "Start Analyze")) 15 { 16 audioreads.ReadAudio(); 17 } 18 } 19}

AudioRead.csのReadAudioの赤線があり、カーソルを合わせると以下のような表示がでます。
イメージ説明

以下のサイトを参考に作成しました。
リンク内容

C#での記述にも慣れておらず、Unity初心者で、
Unity独自の書き方、ソフトの使い方に苦労しております。

どうすれば解決できそうか教えていただきたいです。

また、他のやり方でも、アプリ起動後にGUIのボタンを使って、
保存した音声ファイルを再度取得できるやり方でこちらの方がいい
というのがあれば是非そちらも教えていただければなと思います。

どなたかご教授お願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

yield return www;は普通の関数で使うことは出来ません。
「コルーチン」の中で使用することになります。


今回のエラーとは関係ないですが、以下の問題点もあります。

・AudioReadクラスにMonoBehaviourを継承していないのですが、それだとgameObjectを参照することはできません。
なぜなら、gameObjectはMonoBehaviourのプロパティだからです。

Application.dataPathはエディタ上とビルドしたゲーム上では参照されるディレクトリは違います。
特に、ビルドしたゲーム上ではAssetsディレクトリの内容を直接読み込むことは出来ないのですが、そこは考慮されておりますでしょうか?

今回のプログラムの前に音声をマイクで取得し、保存してから、再び呼び出して音声解析まで
行えるアプリを作りたいと考えているためです。

ということであれば、Application.temporaryCachePath(一時的)かApplication.persistentDataPath(ゲームが終了しても残る)を使うべきなのではないかと思うのですが、どうでしょうか?

・Start_analyze_actionクラスのaudioreadsにオブジェクトを代入する処理がどこにもありません。
このままだとaudioreadsはnullのままなので、audioreads.ReadAudio();でエラーが発生してしまいます。

・OnGUI()は古いものだそうです。
できれば、新しいGUI(uGUIと呼ばれることがある)を使う方がよろしいかと思います。


追記:
www.GetAudioClip()の第2引数がtrueとなっておりますが、もしかしてストリーミング再生を行いたいということでしょうか?
もし、そうなのであれば、yield return www;はロード完了するまで待機するという意味なので、違うのではないかなと思います。

そのため、スクリプトを作り直してみました。
同じファイルを2回ロードしようとするとエラーが出たので、そうならないように変更を加えたコードになります。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class AudioRead : MonoBehaviour 6{ 7 AudioSource source; 8 9 void Start() 10 { 11 // AudioSourceは1度だけ生成するようにする 12 source = gameObject.AddComponent<AudioSource>(); 13 source.playOnAwake = false; 14 } 15 16 public void ReadAudio() 17 { 18 if (source.clip == null || source.clip.loadState == AudioDataLoadState.Failed) 19 { 20 // コルーチンを開始 21 StartCoroutine(LoadAudioCoroutine()); 22 } 23 else if (source.clip.loadState != AudioDataLoadState.Unloaded) 24 { 25 // ロード開始後のみ再生 26 source.Stop(); 27 source.Play(); 28 } 29 } 30 31 IEnumerator LoadAudioCoroutine() 32 { 33 // パスは適宜変更してください 34 using (WWW www = new WWW("file://" + Application.streamingAssetsPath + "/myvoice.wav")) 35 { 36 source.clip = www.GetAudioClip(false, true); 37 38 // ロード開始まで待機 39 while (source.clip.loadState == AudioDataLoadState.Unloaded) 40 { 41 yield return null; 42 } 43 44 source.Play(); 45 46 // ロード完了まで待機 47 yield return www; 48 } 49 } 50}

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Start_analyze_action : MonoBehaviour 6{ 7 // Inspector上からAudioReadをアタッチしたオブジェクトを指定 8 public AudioRead audioreads; 9 10 // uGUIのボタンを作成し、そのボタンのOn Click()に登録する 11 public void OnClickButton() 12 { 13 audioreads.ReadAudio(); 14 } 15}

投稿2018/02/14 13:36

編集2018/02/15 03:07
fiveHundred

総合スコア9803

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

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

kazuh1r010

2018/02/15 02:21

上記のエラーを無事に解決することができ、ご丁寧に他の部分もご指摘いただきありがとうございました。 ただ、fiveHundredさんがおっしゃる通り、 audioreads.ReadAudio();で発生するエラーの解決方法が分からず、 コルーチンに対応させつつエラーを解決するために実行部分のコードを m_coroutineObject.StartCoroutine(audioreads.ReadAudio());に 変更したのですが、ビルドした後以下のような、エラーが出ました。 「NullReferenceException: Object reference not set to an instance of an object」 おそらく、おっしゃっていたオブジェクトの代入のことだと思いますが、 コルーチンを考慮しつつ加える方法が分かりませんでした。 よろしければ、教えていただけないでしょうか?
fiveHundred

2018/02/15 02:53

AudioReadのオブジェクトを取得して格納すればよいです。 あるいはaudioreadsにpublicをつけると、Inspector上から設定できるようになるので、それで指定してもよいです。 これらはコルーチンとは関係はありません。 それと、後で気づいた点があるので、回答に追記したので、それも確認してください。
fiveHundred

2018/02/15 03:08

すいません。追記したスクリプトを若干修正しましたので、確認をお願いします。
kazuh1r010

2018/02/15 06:04

スクリプトまで記述していただき、ありがとうございます。 自分の環境で試してみた結果以下のエラーが返ってきてしまうのですが 考えられる原因が突き止められませんでした。 Error: Cannot create FMOD::Sound instance for resource iBC, (Operation could not be performed because specified sound/DSP connection is not ready. ) エラーか所は、 public void OnClickButton() の audioreads.ReadAudio(); ReadAudio()        の StartCoroutine(LoadAudioCoroutine()); IEnumerator LoadAudioCoroutine() の source.clip = www.GetAudioClip(false, true); と while (source.clip.loadState == AudioDataLoadState.Unloaded) 重ねてになりますが教えていただけませんでしょうか?
fiveHundred

2018/02/15 06:17

パスを「Application.streamingAssetsPath」に変えてますので、それが原因かもしれません。 パスを変更するか、Assetsディレクトリ内に「StreamingAssets」という名前のディレクトリを作ってそれにmyvoice.wavを入れてください。
kazuh1r010

2018/02/15 08:02

新たにディレクトリを作成する方法でエラーが解決しました! まだまだ、先はありますが頑張ろうと思います。 何度も回答いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問