teratail header banner
teratail header banner
質問するログイン新規登録
Unity

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

Q&A

1回答

2884閲覧

ビルド結果が環境で異なってしまう

Asyet_

総合スコア8

Unity

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

0グッド

2クリップ

投稿2018/07/21 17:53

編集2018/07/25 09:48

0

2

前提・実現したいこと

2名でスマートフォン向け2Dシューティングゲーム開発をしています。

2名はそれぞれWindows機/Mac機を使っており、Unityのバージョンは統一し、開発データの同期はUnity標準搭載のCollab機能を利用しています。

直前にCollabしたばかりのデータをビルドしてみると、2名それぞれの環境でのビルド結果に違いがあることがわかりました。

2名での(または今後それ以上の人数での)開発を行う際、ビルド結果に大きな差がある状態は好ましくないと思われるため、ビルド結果を近づける方法を知りたいと考えています。

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

for文で毎フレーム繰り返しているInstantiateの実際の実行頻度に差が生じ、画面上に表示される弾の数(見え方)が異なっています。

Windows環境 ⇒ 高速の連射弾が隙間なく連なって見える
Mac環境 ⇒ 連射弾に隙間が生じることが多く、またその隙間のサイズも弾0.5個〜1.5個分までバラつきがある

該当のソースコード

C#

1for (; ; ) 2 { 3 Debug.Log("Make Bullet"); 4 Instantiate(UpBullet); 5 UpBullet.transform.position = motherTf.position; 6 yield return new WaitForSeconds(ChargeWaitTime); 7 8 }

追加:新たに試したソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PfTimeInsta : MonoBehaviour { 6 7 // 生成したいPrefab 8 public GameObject UpBullet; 9 10 public Transform motherTf; 11 12 bool Shootstate = true; 13 14 public float timeOut = 3; 15 private float timeTrigger; 16 17 18 void Start() 19 { 20 21 } 22 23 void Update() 24 { 25 if (Shootstate == true) 26 { 27 28 if (Time.time > timeTrigger) 29 { 30 31 Instantiate(UpBullet); 32 UpBullet.transform.position = motherTf.position; 33 34 timeTrigger = Time.time + timeOut; 35 36 } 37 } 38 } 39 40 public void StopShoot() 41 { 42 Shootstate = false; 43 } 44 45 public void StartShoot() 46 { 47 if (Shootstate == false) 48 { 49 Shootstate = true; 50 } 51 } 52}

試したこと

両名の環境でGame実行画面のStatsタブをONにしてビルド結果実行中のStatisticsを確認したところ、「Saved by batching」「Tris」「Verts」などの値に大きな差があることがわかりました。

また、QualitySettingsから「V Sync Count」などが揃っているかも確認しましたが、これについては差がありませんでした。
(そもそもがCollabで同期される部分として認識しているのですが…)

その後、「Unity 複数人で開発 実行結果」などで参考となる事例を探しましたが、発見できなかったので質問させていただくことにしました。

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

開発環境のバージョンは両名とも「Unity2017.3.1f1 Personal」です。

特殊な演出を導入するため、Instantiateする弾はAnimation Clipで動かしています。
(Animation Clipで動かされる弾丸を繰り返し生成しています)

また、ビルド結果にはAnimation Clipで動くその他のオブジェクトも含まれていますが。こちらは両環境で同程度の時間で動いていることを確認しています。
(3秒で規定距離を動くオブジェクトが、両環境でも約3秒で移動を完了している、など)

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

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

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

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

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

guest

回答1

0

WaitForSecondsは以下の理由により、正確ではありません。

いくつか要因があり、実際に延期する時間が指定された時間と正確には一致しないことがあります。

  • WaitForSeconds は現在のフレームの 終了時 に待機を始めます。そのため、持続時間 't' を持つ WaitForSeconds をとても長いフレーム (例えば、同期的な読み込みなどのメインスレッドをブロックするような長い操作があるフレーム) で開始すると、コルーチンは、呼び出し後にではなく、そのフレームの終了 後 に 't' 秒を返します。

  • WaitForSeconds によって、コルーチンは正確に 't' 秒後ではなく、't' 秒後に最初のフレームから再開することが可能です。

引用元

私にはいい方法が思いつきませんが、時間を取得して弾の位置や個数を補正すればよいと思います。


追記:

Update()の呼ばれるタイミングも不定です。
「timeTrigger = Time.time + timeOut;」としてしまうと、(遅れる可能性のある)現在の時間からtimeOut秒後ということになるので、やっていることは変更前のソースコードと何も変わりません。

なので、以下のようにする必要があります。

C#

1 void Update() 2 { 3 if (Shootstate == true) 4 { 5 6 if (Time.time > timeTrigger) 7 { 8 9 Instantiate(UpBullet); 10 UpBullet.transform.position = motherTf.position; 11 12 // 変更 13 timeTrigger += timeOut; 14 15 } 16 } 17 } 18 19 public void StartShoot() 20 { 21 if (Shootstate == false) 22 { 23 Shootstate = true; 24 25 // 追加 26 timeTrigger = Time.time; 27 } 28 }

追記2:

これでも直らないということは、おそらく「連射速度が早すぎて、遅い環境だと1フレームに2個生成させないと速い環境に追いつかない」のが原因ではないかなと思います。
以下のようにするのはどうでしょうか?

C#

1 void Update() 2 { 3 if (Shootstate == true) 4 { 5 6 int loopCount = 0; // 追加 7 8 // 変更 9 // 2個以上生成させる為にwhile文に変更 10 while (Time.time > timeTrigger) 11 { 12 13 Instantiate(UpBullet); 14 15 // 変更 16 // そのままだと弾が重なってしまうので、前進方向にずらす 17 // Vector3の距離と向きは適当なので、調節すること 18 // 厳密にやる場合は、時間に応じてVector3の位置を微調整するようにすればよい 19 UpBullet.transform.position = motherTf.position + loopCount * new Vector3(0f, -1f, 0f); 20 21 timeTrigger += timeOut; 22 23 loopCount++; // 追加 24 } 25 } 26 } 27 28 public void StartShoot() 29 { 30 if (Shootstate == false) 31 { 32 Shootstate = true; 33 34 timeTrigger = Time.time; 35 } 36 }

投稿2018/07/22 04:13

編集2018/07/26 10:14
fiveHundred

総合スコア10454

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

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

Asyet_

2018/07/25 09:49

ご返答ありがとうございます。 WaitForSecondsでは環境間でのフレームの差に対応できないようなので、各種のTimeクラスを勉強しながら「時間の取得」「弾の位置や個数の補正」を試しているところです。 参考サイト:https://www.f-sp.com/entry/2016/08/15/190636 Time.timeクラスで所定の時間毎に発射トリガーを更新するやり方を試してみましたが、環境間のばらつきは起きたままでした。 元記事に上記のスクリプトを編集して掲載しました。 しかし、未だ決定的な解決には至っていませんので、回答受付を継続したいと考えています。
fiveHundred

2018/07/25 10:05

回答に追記しました。
Asyet_

2018/07/26 09:51

追加のご回答ありがとうございました。 いただいた修正案を実行してみたのですが、結果として連射弾の見え方の差は残ったままでした。 今後、ひとまずは環境における連射弾の見え方の差異は無視して開発を進め、その他の要素で違和感を解消していく方法を探っていこうと考えております。 度々のご助言ありがとうございました。
fiveHundred

2018/07/26 10:15

気づいた点があるので、回答に追記しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問