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

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

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

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

Q&A

解決済

1回答

1375閲覧

UnityにおけるTime.deltaTimeの単位について

senseIY

総合スコア281

Unity

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

0グッド

1クリップ

投稿2022/11/06 07:40

前提

私が一番最初に学習した参考書(リンク)とこれらのサイト1つ目2つ目のTime.deltaTimeの単位の扱いが異なっているため、どちらが正しいのかわかりません。
*両者ともUpdate関数の中で呼び出すことを前提としております。

前者(猫本)  Time.deltaTime[1/fps = s/f] * fはフレーム sは秒 fpsはf/s

本文の一部を形を変えて抜粋させていただきます。

  例えば、Updateメソッドの中で「プレイヤーの位置をx=1ずつ右に動かす」という処理をしていたとする。その場合「FPS = 60のデバイスでは1秒間に60回Updateメソッドが呼ばれるので、1秒後にはx=60の位置にいることになる」。しかし、「FPS=300のデバイスでは、1秒後にx=300にいることになる」
このような。デバイスの性能による実行計画の違いをなくすために、Updateメソッドの中で移動する距離を「プレイヤの秒速 * Time.deltaTime」とする方法がある。こうすることで、プレイヤの1秒後の位置は「プレイヤの秒速 * Time.deltaTime * FPS」と計算できる。
つまり
プレイヤの1秒後の位置 = プレイヤの秒速 * Time.deltaTime(1/FPS)*FPS

大体このような内容が書かれていました。ここからは私が勝手に考えているだけですが、これらの単位に注目すると、

Time.deltaTime[1/fps = s/f]  ただし、 fはフレーム・sは秒・fpsはf/s

このようになると考えました。
この場合、最終的にプレイヤの秒速[m/s]という単位が出てきます。

後者は  Time.deltaTime[s]

また、1つ目の記事によると、

適当に計算式に混ぜ込めば処理がなめらかになるといった理解は間違いです。答えを言ってしまうと、「右辺にTime.deltaTimeを掛けた時に、左辺と同じ単位になったら使ってもよい」です。

単位には大事な性質があります。1 異なる単位同士は足せない( 距離 + 秒、みたいな計算はできない )2 異なる単位同士は掛け算できる、その場合は別の単位となる(距離 = 速度✕時間、みたいな)3 単位を持たない場合は[1]と表記する(無次元)

さらに、

例2: 速度と速度
続いて、左辺が速度で、この速度を制御したい場合です。この場合、右辺で扱うパラメータが最初から速度であるならばTime.deltaTimeを掛けてはいけません。
これも単位を計算すればすぐわかります。

cs

1public class Sample : MonoBehaviour 2{ 3 /// <summary> 4 /// 速度[m/s] 5 /// </summary> 6 private Vector3 _velocity = new Vector3(1, 0, 0); 7 8 private Rigidbody _rigidbody; 9 10 void Start() 11 { 12 _rigidbody = GetComponent<Rigidbody>(); 13 } 14 15 void Update() 16 { 17 // [m/s] = [m/s] * [s] 18 // [m/s] = [m] ←???????? 19 _rigidbody.velocity = _velocity * Time.deltaTime; // 間違い 20 21 // この場合は普通に代入するだけでよい 22 _rigidbody.velocity = _velocity; 23 } 24}

このようにありました。
詳しくは1つ目の記事を読んでいただければ幸いです。

自身の考察と疑問

*私は元々文系で数学はかなり苦手なため、ナンセンスな質問をしているかもしれません。その場合はご指摘をいただけますと幸いです。

結局のところどっちが正しいのか

私は前者(猫本)が正しいような気がします

後者に

cs

1 void Update() 2 { 3 // [m/s] = [m/s] * [s] 4 // [m/s] = [m] ←???????? 5 _rigidbody.velocity = _velocity * Time.deltaTime; // 間違い 6 7 // この場合は普通に代入するだけでよい 8 _rigidbody.velocity = _velocity; 9 }

このようにありましたが、私は

cs

1 void Update() 2 { 3 _rigidbody.velocity = _velocity * Time.deltaTime * FPS(FPSはUpdate内で強制的にかかる); 4 // 本来ならばUpdateの中にはFPSがかかっていることを考慮するべきなので上の例は 5// [m/s] = [m/s] * [s/f(1/FPS)]*[f/s(FPS)] だからOK 6 // よってTime.deltaTimeをかけてもOK 7 _rigidbody.velocity = _velocity * Time.deltaTime; 8 }

このように考えました。

また、
1 そもそも、単位は両辺合わせないとダメなのか
2 Unityのベクトルには単位はつくのか(リンク

この質問に対しても何かしらアドバイスがあれば教えていただきたいです。誤字脱字があった場合には追記いたします。よろしくお願いいたします。

*私の稚拙な質問で気分を害された場合は申し訳ございません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

まずリファレンスを見てみます

The interval in seconds from the last frame to the current one (Read Only).

Time-deltaTime - Unity スクリプトリファレンス

前のフレームから現在のフレームまでの秒単位の間隔ですね、ということは単位はsecで良さそうです。
しかし実のところs/fとして扱ってもさして問題ありません。式の解釈が変わるだけです。


位置xを毎フレーム変化させて、一定速度で動かそうとすることを考えます。

Update()中で、x[m]v[m/s]としたとき、

c#

1dx += v * Time.deltaTime; 2x += dx;

とすれば(vが定数であれば)一定速度でxが変化することは明らかかとおもいます。
(明らかでない場合はコメントください)

まず問題文の登場順と前後しますがまずTime.deltaTimeが単位sとする解釈の方です。
この場合はdxの単位はmになります。
Update()中で」という文脈で出てきているので、dxは「前回フレームからの移動量」を表しています。
x += dxというのも左右で単位はmで揃っていますね。

さて次はTime.deltaTimeをフレーム単位の経過時間s/fとする解釈です。
こちらはdxの単位はm/fです。フレームあたりの移動量ですね。
したがって、dxに前回計算時からの経過フレーム数n[f]を掛けたものがxの増加量になります。
ですからxを増加させる処理の部分は本来であればx += n * dxですね。
ここで、Update()というのはそもそも毎フレーム呼び出されるものですからn=1[f]です。
1倍するのは計算上省略可能ですので、
暗黙上で1[f]が乗算されているものとしてx += dxと書いてあると解釈します。

結局Update()内で毎フレーム処理する限り、どちらの単位でも処理を解釈できます。


(FPSはUpdate内で強制的にかかる)

かかりません。

1 そもそも、単位は両辺合わせないとダメなのか

はい。物理量は数値と単位の掛け算で表されます。
例えば速さ100m/sというのは 数値100に単位m/sを掛けています。

1m1kgは数値部分は1で共通ですが、掛かっている単位が違うので 1m ≠ 1kg です、当たり前ですね。

2 Unityのベクトルには単位はつくのか(リンク)

つく場合もありますし、つかない場合もあります。12-123.45などといった数値に単位が付きますか?
それが何を表しているかによりますよね。

ベクトルであっても一緒です。
「このベクトルは速度を表すことにしよう、単位はm/sだ」とすることもあれば、
「このベクトルは方向を表すことにしよう」とすれば無次元量です。

投稿2022/11/07 00:18

編集2022/11/07 00:19
ozwk

総合スコア13521

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

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

senseIY

2022/11/07 01:09

とても丁寧に回答していただきありがとうございました。どうやら自分は猫本の説明を誤解していたようです。 猫本にあった「プレイヤの1秒後の位置 = プレイヤの秒速 * Time.deltaTime(1/FPS)*FPS」この記述を ``` cs void Update() { _rigidbody.velocity = _velocity * Time.deltaTime * FPS(FPSはUpdate内で強制的にかかる); // 本来ならばUpdateの中にはFPSがかかっていることを考慮するべきなので上の例は // [m/s] = [m/s] * [s/f(1/FPS)]*[f/s(FPS)] だからOK // よってTime.deltaTimeをかけてもOK _rigidbody.velocity = _velocity * Time.deltaTime; } ``` このようにUpdateメソッドの中にFPSをかけるものだと誤った認識をしていました。確かに、猫本には、「プレイヤの1秒後の位置 = プレイヤの秒速 * Time.deltaTime(1/FPS)*FPS」という趣旨の記述がありましたが、これがUpdateメソッドの中の式になるとは書いていませんでした(コードの記載が無く、式と言葉での説明だった)。  ozwk様のおっしゃる通り、「プレイヤの1秒後の位置 = プレイヤの秒速 * Time.deltaTime(1/FPS)*FPS」という式をコードで記載する場合には、 ``` cs void Update() { dx += v * Time.deltaTime; /// [m/f] = [m/s] * [s/f] x += dx (* 1f); /// [m] = [m/f] * [f] (Updateメソッドは1fごとに呼び出されるため、暗黙的に1fがかけられていると解釈することができる) } ``` このように解釈するべきですね。 1 そもそも、単位は両辺合わせないとダメなのか 2 Unityのベクトルには単位はつくのか これらについても理解できました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問