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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

2回答

580閲覧

Unity)メンバー変数で取得できない

navesanta

総合スコア198

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2020/01/18 05:22

編集2020/01/18 08:32

UnityでAddressableを使っているのですが
Addressableで取得したAudioClipの長さをBlock外で取得したいのですが
どうすればできるでしょうか?
メンバー変数で定義すればそのクラス内では取得できると思っていたのですが
違うのでしょうか?ルールがあるのでしょうか?

環境)
PC: mac
Unity2018.3.0f2
言語:C#

具体例)

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; public class Test2Script : MonoBehaviour { #pragma warning disable 649 [SerializeField]GameObject SoundsObject; [SerializeField]GameObject ImageObject; AudioSource testAudioSource; AudioClip audioClip; float audioClipNum; //メンバー変数で定義する // Start is called before the first frame update void Start() { Debug.Log("OutBlock" + AddressableScript()); //0になってしまう(取得できない) } float AddressableScript() { Addressables.LoadAssetAsync<AudioClip>("Assets/Sounds/epinpon.ogg").Completed += op => { audioClip = op.Result as AudioClip; SoundsObject.GetComponent<AudioSource>().PlayOneShot(audioClip);  audioClipNum = audioClip.length; Debug.Log("InBlock" + audioClipNum); //ここでは正しい値が表示される }; return audioClipNum; } } //結果: OutBlock = 0 //結果: InBlock = 1.567347

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

ソースコード

試したこと

IEnmuratorを使って処理を非同期終了後に起きるようにしましたが
やはり取得することができません。

修正したコードは下記です。

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; public class Test2Script : MonoBehaviour { #pragma warning disable 649 [SerializeField]GameObject SoundsObject; [SerializeField]GameObject ImageObject; AudioSource testAudioSource; AudioClip audioClip; float audioClipNum; //メンバー変数で定義する // Start is called before the first frame update void Start() { testAudioSource = SoundObject.GetComponent<AudioSource>(); StartCoroutine("AddressableScript"); } IEnumerator AddressableScript() { Addressables.LoadAssetAsync<AudioClip>("Assets/Sounds/epinpon.ogg").Completed += op => { audioClip = op.Result as AudioClip; SoundsObject.GetComponent<AudioSource>().PlayOneShot(audioClip);  audioClipNum = audioClip.length; Debug.Log("InBlock" + audioClipNum); //ここでは正しい値が表示される }; yield return null; Debug.Log("OutBlock = " + audioClipNum); } } //結果: OutBlock = 0 //結果: InBlock = 1.567347

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

IEnmuratorを使って処理を非同期終了後に起きるようにしましたが
やはり取得することができません。

全くもって、そうなっておりません。
yield return null;は1フレーム分待機するというものなので、音声ファイルの読み込み時間がそれ以上かかった場合、先にDebug.Log("OutBlock = " + audioClipNum);が行われます。
というか、そもそも提示の結果表示にも、OutBlock = 0が先に出ているため、なぜそう判断したのかが、私には分かりません。

以下のように、ロードが完了したかどうかのフラグ変数を用意し、それが変更されていれば続きを実行する、というのはどうでしょうか。

C#

1 bool isLoadFinished = false; 2 3 IEnumerator AddressableScript() 4 { 5 Addressables.LoadAssetAsync<AudioClip>("Assets/Sounds/epinpon.ogg").Completed += op => 6 { 7 audioClip = op.Result as AudioClip; 8 SoundsObject.GetComponent<AudioSource>().PlayOneShot(audioClip); 9 audioClipNum = audioClip.length; 10 Debug.Log("InBlock" + audioClipNum); 11 12 isLoadFinished = true; 13 }; 14 15 while (!isLoadFinished) 16 { 17 yield return null; 18 } 19 20 Debug.Log("OutBlock = " + audioClipNum); 21 }

投稿2020/01/18 09:41

fiveHundred

総合スコア9778

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

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

navesanta

2020/01/18 21:15

今まで非同期の処理で終了したときのメソッドを探しても 見当たらず悩んでいました。目から鱗が落ちたようです。 わかりやすい解説ありがとうございました。 説明を聞いてみれば確かに仰るとおりです。 これからもよろしくお願いします。
guest

0

実際に取得するロジック部分が動いているか確認してみてください。

私はUnityは詳しくないのでソースを見て読み取れる部分でお答えします。

C#

1 Addressables.LoadAssetAsync<AudioClip>("Assets/Sounds/epinpon.ogg").Completed += op => 2 { 3 audioClip = op.Result as AudioClip; 4 SoundsObject.GetComponent<AudioSource>().PlayOneShot(audioClip); 5  audioClipNum = audioClip.length; 6 Debug.Log("InBlock" + audioClipNum); //ここでは正しい値が表示される 7 }; 8

こちらですが、AudioClipをAsync(非同期)にて読み込み、その読み込みが終了した時の動作を設定しています。
その動作の中でaudioClipNum を設定しているわけですが、この次の行の

C#

1return audioClipNum;

この行が実行される時点ではまだ読み込みが完了しておらず、audioClipNum = audioClip.length;この行もまだ実行されていないのではないでしょうか?
OutBlockとInBlockのどちらが早く表示されているか確認すれば分かるのではないかと思います。

ではどうやるのがいいのかなのですが、いわゆるUnityでのお約束的な部分が私には分かりません。

投稿2020/01/18 05:55

YAmaGNZ

総合スコア10222

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問