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

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

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

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

Q&A

2回答

2184閲覧

Unity 実機テストでスマホによりボール速度が違う

taiyaki

総合スコア0

Unity

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

0グッド

0クリップ

投稿2022/04/10 13:45

編集2022/04/11 14:15

PCでUnity2Dを使ってブロック崩しを作りました。
PC上でプラットフォームをPC、Androidどちらで試しても想定通りに動きました。
そこで実機テストでAndroidのスマホ2台(A,B)を試したところ、ボールの移動速度がスマホAは想定通り、スマホBは遅い(印象でスマホAの60%程度)結果となり困っています。

試したこと

1)ボールの移動はFixedUpdate関数を使いProject Settings >> 時間 >> 固定時間ステップを0.02、0.0166、0.01の3種類を試す。

2)ボールの移動はUpdate関数を使いProject Settings >> 品質 >> VSync 数を 同期しない にしてGameManagerスクリプトで
void Awake()にApplication.targetFrameRate = 60;を記述。
Project Settings >> 品質 >> 品質レベルのチェックをHighのみにする。

以上の2つを試してみても結果は同じでした。

使用スマホ
スマホA:Galaxy A20 SC-02M 2019年製 リフレッシュレート不明
スマホB:SHARP AQUOS sense4 basic 2020年製 リフレッシュレート60HzHz

スマホの機種によらず移動速度を安定させる方法をネット検索しても他に見つからず、手詰まりとなってしまいました。
どなたかアドバイスをいただけませんでしょうか。
お願いいたします。

【追加】
ボールのコードを追加いたします。

C#(cs)

1public class Ball : MonoBehaviour 2{ 3 public float speed = 100f; // ボールの移動の速さを指定する変数 4 public float minSpeed = 100f; // 速さの最小値を指定する変数 5 public float maxSpeed = 150f; // 速さの最大値を指定する変数 6 7 Vector3 vec; 8 Rigidbody2D myRigidbody; 9 Transform myTransform; 10 GameObject objBlock; 11 GameObject objPlayer; 12 BlockT block; 13 Player player; 14 float point; // ボールとプレイヤーの接触時のx座標差 15 float defference; // プレイヤーの1/8の長さに対するボールとプレイヤーのx座標差 16 float ballblockgap; // ボールとブロックの接触時のx座標差 17 18 void Start() 19 { 20 // Rigidbodyにアクセスして変数に保持しておく 21 myRigidbody = GetComponent<Rigidbody2D>(); 22 // 右斜め45度に進む 23 myRigidbody.velocity = new Vector3(speed * x, speed * y, 0f); 24 // 画面描画用のCanvasを取得 25 var canvas = GetComponentInParent<Canvas>(); 26 // Transformコンポーネントを取得して保持しておく 27 myTransform = transform; 28 } 29 30 // 衝突したときに呼ばれる 31 void OnCollisionEnter2D(Collision2D collision) 32 { 33 Vector3 objBall = myTransform.position; 34 Vector3 objPlayer = GameObject.Find("Player").transform.position; 35 var playerRectTransform = GameObject.Find("Player").GetComponent<RectTransform>(); 36 // プレイヤーの位置を取得 37 Vector3 playerPos = collision.transform.position; 38 // Rigidbodyにアクセスして変数に保持しておく 39 myRigidbody = GetComponent<Rigidbody2D>(); 40 // 画面描画用のCanvasを取得 41 var canvas = GetComponentInParent<Canvas>(); 42 43 if (collision.gameObject.CompareTag("Block")) 44 { 45 // ボールとブロックの接触時のx座標差 46 float ballblockgap = collision.contacts[0].point.x - objBall.x; 47 48 if (ballblockgap > 5f) 49 { 50 // 225度に進む 51 myRigidbody.velocity = new Vector3(speed * -1f, speed * -1f, 0f); 52 // Transformコンポーネントを取得して保持しておく 53 myTransform = transform; 54 } 55 // 反射角はボールとブロックの接触時のx座標差によって分けています。 56 // 反射角は上記new Vector3のようにボールのスピードに掛ける数値(f)を変えることで指定しています。 57 // 指定角度の数だけ同じパターンの記述が続くので省略します。 58 } 59 if (collision.gameObject.CompareTag("Player")) 60 { 61 // ボールとプレイヤーの接触時のx座標差 62 float point = collision.contacts[0].point.x - objPlayer.x; 63 // プレイヤーの1/8の長さに対するボールとプレイヤーのx座標差 64 float defference = point / ((playerRectTransform.sizeDelta.x) / 8); 65 66 if ((defference > 3.5) && (defference <= 4)) 67 { 68 // 45度に進む 69 myRigidbody.velocity = new Vector3(speed * 1f, speed * 1f, 0f); 70 // Transformコンポーネントを取得して保持しておく 71 myTransform = transform; 72 } 73 // 反射角はボールとプレイヤーの接触時のx座標差によって分けています。 74 // 反射角は上記new Vector3のようにボールのスピードに掛ける数値(f)を変えることで指定しています。 75 // 指定角度の数だけ同じパターンの記述が続くので省略します。 76 } 77 } 78 // 毎フレーム速度をチェックする 79 void Update() 80 { 81 // 現在の速度を取得 82 Vector3 velocity = myRigidbody.velocity; 83 // 速さを計算 84 float clampedSpeed = Mathf.Clamp(velocity.magnitude, minSpeed, maxSpeed); 85 // 速度を変更 86 myRigidbody.velocity = velocity.normalized * clampedSpeed; 87 } 88}

コードを全部ではありませんが、ボールの動くコードは載せられたと思います。
こちらでいかがでしょうか。

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

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

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

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

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

mike2mike4

2022/04/10 13:51

機種による処理速度の差を考慮した設計になってますでしょうか?
taiyaki

2022/04/10 14:08

早速のお返事ありがとうございます。 FixedUpdateが機種による処理速度の差を埋めてくれるものと理解していました。 ご指摘の点についてもう少し調べてみようと思います。 ありがとうございました。
guest

回答2

0

  • On mobile platforms the default frame rate is less than the maximum achievable frame rate due to the need to conserve battery power. Typically on mobile platforms the default frame rate is 30 frames per second.

https://docs.unity3d.com/2019.4/Documentation/ScriptReference/Application-targetFrameRate.html
こちらに書いてあるようにモバイルでは基本的にUnity側が上限30fpsで制限していますが、現状それが端末側の仕様で解除されたりされなかったりしています。

管理オブジェクトのstartかawakeに

Application.targetFrameRate = 60;

を書き強制60fps指定にすれば間違いはないと思うのでお試しください。

投稿2022/04/12 05:28

UnchFullburst

総合スコア663

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

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

taiyaki

2022/04/12 08:57

UnchFullburstさん、ご回答ありがとうございました。 端末側で解除されたりされなかったりするのですね。 ご提案いただいたフレームレートを固定する方法につきまして、これまで自分で試した方法との違いも含めて再確認してみたいと思います。
guest

0

Time.deltaTimeは使っていますか?前フレームからの経過時間を表しているので、速度ベクトルにTime.deltaTimeをかけるとどの機種でもボールの移動速度が一定になります。speedは1秒間に進む移動ベクトルを表します。

cs

1void Update() 2{ 3 position += speed * Time.deltaTime; 4}

【追記】

調べてみましたが、velocityを直接変更することは推奨されていないようです↓

ほとんどの場合、速度を直接変更しないでください。これにより、非現実的な動作が発生する可能性があります。代わりにAddForceを使用してください。

スクリプトリファレンス - Rigidbody.velocity

AddForceメソッドを使うなら

AddForceを使った移動においての速度制限に関して、私は以下のブログを参考にしました↓

UnityのRigidbodyのAddForceを使ったキャラクターの移動スクリプト

MovePositionメソッドもある

また、RigidbodyコンポーネントのisKinematicにチェックを入れて、ボールが等速直線運動しかしないと仮定するならRigidbodyのMovePositionメソッドを使うというのも1つの方法かと思います。

スクリプトリファレンス - Rigidbody .MovePosition

投稿2022/04/11 01:44

編集2022/04/12 07:20
KomoriGameDev

総合スコア433

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

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

taiyaki

2022/04/11 10:49

KomoriGameDevさんありがとうございます。 現在、以下(かなり簡略してます)のように書いているためTime.deltaTimeは使えないだろうと認識しています。 ```C#(cs) float speed = 100f; void Start(){ myRigidbody = GetComponent<Rigidbody2D>(); myRigidbody.velocity = new Vector3(speed, speed, 0f); // 45度に進む } // ブロックに衝突した時 void OnCollisionEnter2D(Collision2D collision){ myRigidbody.velocity = new Vector3(speed * -1f, speed * -1f, 0f); // 225度に進む myTransform = transform; } void Update(){ Vector3 velocity = myRigidbody.velocity; // 現在の速度を取得 // 速さを計算 float clampedSpeed = Mathf.Clamp(velocity.magnitude, minSpeed, maxSpeed); myRigidbody.velocity = velocity.normalized * clampedSpeed; // 速度を変更 } ``` 以前に`myRigidbody.velocity = velocity.normalized * clampedSpeed * Time.deltaTime;`と書いたら極端に速度が遅くなり、検索したら使い方が正しくないことが分かりました。 Time.deltaTimeを使う場所が違うのか、そもそも使えないのか、使うのなら書き換えが必要なのかの判断がつかず、検索で見つけたFixedUpdate関数が最短で解決できる救世主に見えました。が、うまくいきませんでした。 上記の抜粋コードから何か分かることがあればアドバイスいただけますと幸いです。 現在Unityの設定から見直しています。
KomoriGameDev

2022/04/11 11:11 編集

提示して頂いたコードは、見にくいので質問の方に追記して頂くと助かります。 それと、簡略化するのではなく動かしているコードをそのまま貼り付けてもらったほうが解決できる確率は上がると思います。
KomoriGameDev

2022/04/12 07:23

回答に追記したので、試してみてください。
taiyaki

2022/04/12 09:10

KomoriGameDevさん、わざわざ調べてくださり、ありがとうございます。 ボールの移動方法の書き直しも検討しないといけないかもしれませんね。 これから調べてみます。 また質問させていただくかもしれませんが、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問