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

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

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

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

Q&A

1回答

1952閲覧

UnityのStartCoroutineで非同期処理が動作しない

yrema

総合スコア287

Unity

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

0グッド

0クリップ

投稿2020/06/18 15:23

編集2020/06/18 16:14

ファイルのロード中にGameObjectを回転させたいのですが、
下記の通りStartCoroutineでファイルを読み込ませていますが、
ロード中もUpdate()が走らないようで回転してくれません。
StartCoroutineの使い方を何か間違っているでしょうか?

c#

1public class TestScript : MonoBehaviour { 2 private GameObject Monster { get; set; } 3 private float Speed { get; set; } = 3; 4 private bool Loaded { get; set; } = false; 5 6 void Start () { 7 Monster = GameObject.Find("monster"); 8 } 9 10 void Update() { 11 Monster.transform.Rotate(new Vector3(0, 0, Speed)); 12 if (!Loaded) { 13 StartCoroutine(ReadSaveDataFileAsync(Application.persistentDataPath + "/Test.sav")); 14 } 15 } 16 17 public IEnumerator ReadSaveDataFileAsync(string filePath) { 18 string fileName = filePath; 19 SaveData saveData = (SaveData)LoadFromBinaryFile(fileName); 20 yield return 0; 21 Loaded = true; 22 } 23 24 // ファイル読込 25 public static object LoadFromBinaryFile(string path) { 26 FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); 27 BinaryFormatter f = new BinaryFormatter(); 28 object obj = f.Deserialize(fs); 29 fs.Close(); 30 return obj; 31 } 32}

▼追記1 async/awaitを使用(これでも変わらず)

c#

1public class TestScript : MonoBehaviour { 2 private GameObject Monster { get; set; } 3 private float Speed { get; set; } = 3; 4 private bool Loaded { get; set; } = false; 5 6 void Start () { 7 Monster = GameObject.Find("monster"); 8 } 9 10 void Update() { 11 Monster.transform.Rotate(new Vector3(0, 0, Speed)); 12 if (!Loaded) { 13 Loaded = true; 14 Task nowait = ReadSaveDataFileAsync(Application.persistentDataPath + "/Test.sav"); 15 } 16 } 17 18 public async Task ReadSaveDataFileAsync(string filePath) { 19 string fileName = filePath; 20 SaveData saveData = (SaveData)LoadFromBinaryFile(fileName); 21 await Task.Delay(0); 22 } 23 24 // ファイル読込 25 public static object LoadFromBinaryFile(string path) { 26 FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); 27 BinaryFormatter f = new BinaryFormatter(); 28 object obj = f.Deserialize(fs); 29 fs.Close(); 30 return obj; 31 } 32}

◆環境
Unity2019.2.17f1
Windows10

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

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

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

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

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

guest

回答1

0

コルーチンは実質的に非同期ではありません。
あくまでUnity側でよしなに非同期っぽく処理してくれているに過ぎないんです。

なので、今回の例のように、ひとつの処理が重い場合はフリーズしたようになってしまいます。
イメージ的には、毎フレーム少しずつ処理をしてくれるイメージです。(なので処理自体はメインスレッドで実行されます)

ファイル読み込みはasync / awaitが使えるので、そちらで実装したら改善すると思います。

投稿2020/06/18 15:50

edo_m18

総合スコア2283

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

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

yrema

2020/06/18 16:15

ご回答ありがとうございます。質問文に「追記1」を追加しました。 async/awaitを使ってみましたが、動作は変わらないようです。
edo_m18

2020/06/19 04:40

これ、そもそもUpdate内で呼ぶ必要ってありますか? Start内で一度呼んであげるだけで良い気がします。
yrema

2020/06/19 05:33

すみません、質問のコードはここに貼り付けるために簡潔にしたもので、実際はボタンを押してフラグがたったら読込開始するでUpdate()内から呼ばれる前提でお願いします。
edo_m18

2020/06/19 15:18

コードちゃんと見てなかったのですが、これだとやはり、まだ同期的にファイルをロードしていると思います。 `async`を使ったから非同期になるわけではなく、ロード処理自体を非同期版にしないと結局、メインスレッドを止めてしまうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問