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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1421閲覧

unityコルーチンで重い処理を素早く終わらせたい

mokayuki0307

総合スコア11

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2018/03/28 15:42

編集2018/03/28 16:05

前提・実現したいこと

切った木を保存して次回ゲーム起動時に切れたままにしたい
unityコルーチンで重い処理を素早く終わらせたい

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

Terrainの木の位置情報、高さなどをクラスのパラメータ配列に入れてから
BinaryFormatterでシリアライズしてからEasysaveで保存する処理

クラスのパラメータ配列に入れるとき保存する木の本数が5万本あるので
コルーチンで実行しないとクラッシュしてしまう
for文の中にyield return null;を入れるとクラッシュしないが
5万本の木のデータを配列に入れるスピードが遅すぎるので
クラッシュせずにスピーディに処理を完了させる方法はありませんか?

該当のソースコード

C#

1private IEnumerator SaveCoroutine() 2{ 3 4 TerrainTreeData treeData1 = new TerrainTreeData(); 5 6 //現在のテライン上の木の本数 7 int treeInstanceCountA1 = TerrainA1.terrainData.treeInstanceCount; 8 9 10 treeData1.HeightScaleA1 = new float[treeInstanceCountA1]; 11 treeData1.PositionXA1 = new float[treeInstanceCountA1]; 12 treeData1.PositionYA1 = new float[treeInstanceCountA1]; 13 treeData1.PositionZA1 = new float[treeInstanceCountA1]; 14 treeData1.PrototypeIndexA1 = new int[treeInstanceCountA1]; 15 treeData1.RotationA1 = new float[treeInstanceCountA1]; 16 treeData1.WidthScaleA1 = new float[treeInstanceCountA1]; 17 18 //この部分の計算に時間がかかってしまう 19 //yield return null;を書かないとUnityエディタがクラッシュしてしまう 20     //treeInstanceCountA1の数が50000 21 for (int i = 0; i < treeInstanceCountA1; i++) 22 { 23 treeData1.HeightScaleA1[i] = TerrainA1.terrainData.treeInstances[i].heightScale; 24 treeData1.PositionXA1[i] = TerrainA1.terrainData.treeInstances[i].position.x; 25 treeData1.PositionYA1[i] = TerrainA1.terrainData.treeInstances[i].position.y; 26 treeData1.PositionZA1[i] = TerrainA1.terrainData.treeInstances[i].position.z; 27 treeData1.PrototypeIndexA1[i] = TerrainA1.terrainData.treeInstances[i].prototypeIndex; 28 treeData1.RotationA1[i] = TerrainA1.terrainData.treeInstances[i].rotation; 29 treeData1.WidthScaleA1[i] = TerrainA1.terrainData.treeInstances[i].widthScale; 30 31 yield return null; 32 33 } 34 35 //セーブ 36 BinaryFormatter bf1 = new BinaryFormatter(); 37 MemoryStream saveMem = new MemoryStream(); 38 bf1.Serialize(saveMem, treeData1); 39 ES2.Save(saveMem.ToArray(), "TreeData.txt?tag=binary"); //Easysave byte配列で保存. 40 saveMem.Close(); 41} 42 43 private void OnGUI() 44 { 45    //セーブボタンを押すと実行 46 if (GUILayout.Button("Save")) 47 { 48 StartCoroutine("SaveCoroutine"); 49 } 50 }

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

Unity 2017.1.1f1

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

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

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

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

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

guest

回答1

0

ベストアンサー

TerrainA1.terrainData.treeInstancesの取得にかなりの処理コストがかかっているようです。これを取得するのはループ前の1回だけでいいのではないでしょうか?

C#

1// 変更...コルーチン化しなくてもレスポンス上問題なさそうだったので、通常のメソッドにしました 2private void Save() 3{ 4 5 TerrainTreeData treeData1 = new TerrainTreeData(); 6 7 //現在のテライン上の木の本数 8 int treeInstanceCountA1 = TerrainA1.terrainData.treeInstanceCount; 9 10 11 treeData1.HeightScaleA1 = new float[treeInstanceCountA1]; 12 treeData1.PositionXA1 = new float[treeInstanceCountA1]; 13 treeData1.PositionYA1 = new float[treeInstanceCountA1]; 14 treeData1.PositionZA1 = new float[treeInstanceCountA1]; 15 treeData1.PrototypeIndexA1 = new int[treeInstanceCountA1]; 16 treeData1.RotationA1 = new float[treeInstanceCountA1]; 17 treeData1.WidthScaleA1 = new float[treeInstanceCountA1]; 18 19 TreeInstance[] treeInstances = TerrainA1.terrainData.treeInstances; // 追加...treeInstancesをループ内で毎回取得する代わりに、ループ前に1回だけ取得する 20 21 //この部分の計算に時間がかかってしまう 22 //yield return null;を書かないとUnityエディタがクラッシュしてしまう 23 //treeInstanceCountA1の数が50000 24 // 変更...先ほど取得したtreeInstancesからデータを取り出すようにした 25 for (int i = 0; i < treeInstanceCountA1; i++) 26 { 27 TreeInstance treeInstance = treeInstances[i]; 28 29 treeData1.HeightScaleA1[i] = treeInstance.heightScale; 30 treeData1.PositionXA1[i] = treeInstance.position.x; 31 treeData1.PositionYA1[i] = treeInstance.position.y; 32 treeData1.PositionZA1[i] = treeInstance.position.z; 33 treeData1.PrototypeIndexA1[i] = treeInstance.prototypeIndex; 34 treeData1.RotationA1[i] = treeInstance.rotation; 35 treeData1.WidthScaleA1[i] = treeInstance.widthScale; 36 } 37 38 //セーブ 39 BinaryFormatter bf1 = new BinaryFormatter(); 40 MemoryStream saveMem = new MemoryStream(); 41 bf1.Serialize(saveMem, treeData1); 42 ES2.Save(saveMem.ToArray(), "TreeData.txt?tag=binary"); //Easysave byte配列で保存. 43 saveMem.Close(); 44} 45 46 private void OnGUI() 47 { 48    //セーブボタンを押すと実行 49 if (GUILayout.Button("Save")) 50 { 51 Save(); 52 } 53 }

投稿2018/03/28 22:21

Bongo

総合スコア10807

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

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

mokayuki0307

2018/03/29 02:58

クラッシュすることなく無事動きました! 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問