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

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

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

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

Q&A

解決済

2回答

14737閲覧

transform.positionとtransform.Translateだとどちらが適切か。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

1クリップ

投稿2018/06/08 09:39

編集2018/06/08 09:41

前提・実現したいこと

ゲームオブジェクトの位置移動では、
transform.positionを変える方法とtransform.Translateによる方法があると思いますが、
この2つの違いや、どちらが適切かをご教示いただけませんか?
一定の速度で自然に移動させたいと考えています。
また、今回、一定の速度で移動させることを考えているので、Rigidbodyを使った移動は考えていません
(Rigidbodyは一定の速度で移動しないはず)。

試したこと

こちらのサイトによると、
transform.Translateよりもtransform.positionの方が処理速度が速いと書かれていました。
単純にこれだけの情報で考えると、transform.Translateよりもtransform.positionを変えたほうがいいように思えますが、
transform.Translateを使う利点はないのでしょうか?

何かのサイトで、transform.Translateはtransform.positionを変えるよりも動きが滑らかになると書かれていたのを見た気がするんですが、(それがうろ覚えでそのサイトのURLも忘れてしまい、本当にそう書かれていたかどうかも自信がないのですが)、
本当でしょうか?

動きが滑らかになるのが本当であれば、多少処理速度が遅くてもtransform.Translateを使いたいと考えています。

また一定の速度で移動させたいので、transform.Translateでもtransform.positionでも、どちらの場合でも、
Time.deltaTimeは掛けるべきでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

transform.positionは「指定の場所に移動」、
transform.Translateは「現在地から指定の値だけ移動」です。

例えばUpdate内で
transform.position = Vector3.right;とすれば「(1,0,0)に居続ける」ことになりますし、
transform.Translate(Vector3.right);とすれば「ワールド空間(1,0,0)方向に移動し続ける」ことになります。

逆に言えば
transform.position = transform.position + Vector3.right;
transform.Translate(Vector3.right);は同じです。

で、リンク先のサイトですが、これ怪しい気がします。
「一定距離を一定回数移動した時間」を測っているとすれば、フレームレートに応じて変わります。
わかりやすいように1フレームあたりの移動量を「1m」、1回分の目標距離を「60m」とした場合、
60fpsの時は「1秒」で移動が完了しますが、30fpsの時は「2秒」かかります。
(1秒間に30回移動する=1秒間で30mしか進めない=60m進むには2秒かかる)

フレームレートは何もしなくても微妙にブレるものなので、例示されている誤差はすぐ出るのではないでしょうか。
また、数回実行した平均を取るべきでもあります。
(※実際に試してはいないので本当にtransform.Translateの方が早い可能性はあります)

この為、普通は係数に0.1fではなくTime.deltaTimeを使います。
これは「前回のフレームからの経過時間」なので係数として使うと、上記の例で言うと1フレームあたりの移動距離を60fpsの時は「1m」、30fpsの時は「2m」にしてくれるイメージです。

また上記の通り、positionもTranslateも移動するだけの処理なので、これを使ったからって動きが滑らかになる訳では無いです。
(もちろん移動量を小さくすれば滑らかに見えますがその分移動速度が遅くなります。早ければ途切れ途切れに見えます。現実世界と一緒です)

投稿2018/06/08 11:25

sakura_hana

総合スコア11425

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

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

退会済みユーザー

退会済みユーザー

2018/06/08 11:49 編集

ご回答ありがとうございます。 positionとTranslateの違いがわかりました。 一応、確認させていただきたいのですが、下記2点は合っていますか? ・衝突を考慮するならば、そもそもtransform系の移動が非推奨。 ・velocityで設定するのであれば、Rigidbodyでも一定速度で移動できる(Rigidbodyでの移動はAddForceのように全て一定の速度でないと思い込んでいました)。
sakura_hana

2018/06/08 11:56

1つ目は、衝突=物理演算とするならばYes。(座標の比較等によって衝突判定を自力実装してやんよ!というケースならtransform系でもOK) 2つ目はnegitamaさんのコメントで回答してしまいましたが、velocity以外でも一定速度での移動は一応可能です。(条件が限られるのでvelocity使った方が早いケースがほとんどですが)
退会済みユーザー

退会済みユーザー

2018/06/09 00:22 編集

ご回答ありがとうございます。 velocity以外の方法を下記のように検証してみましたが(第2引数はVelocityChangeが最適と思いました)、 //右キーを押したときの処理。 rb.AddForce(Vector3.right, ForceMode.VelocityChange); これでも確かに一定速度で動くのですが、 左キーを押したときにも、 //左キーを押したときの処理。 rb.AddForce(Vector3.left, ForceMode.VelocityChange); とすると、右キーで右移動していた状態から、左キーで左移動に切り替えようとすると、 velocityのときの実装とは違い、右から左への切り替え時に(おそらく)慣性の法則が働いてしまい、 スムーズな切り替えにはならなかったです(左移動開始時に、加速してから一定速度に達しました。 velocityで実装した場合は、切り替え時も瞬時に一定速度で左移動しました)。 移動の切り替えも考慮すると、velocityを設定する方法しかないということでしょうか?
sakura_hana

2018/06/09 04:31

右への力を打ち消す為に一時的に左への力が多めに掛かってる感じなのかなーと思います。 結局どれがいいかは「どう見せたいか」によるので、完全にキビキビ動かしたいならvelocity直接指定になるのではないかと思います。
退会済みユーザー

退会済みユーザー

2018/06/09 05:24

ご回答ありがとうございます。 大変勉強になりました。 ありがとうございます。
guest

0

移動に関する処理については、こちらの記事内の比較が面白いと思います。

「僕Unityできますよ」Tシャツのコードレビュー - Qiita
https://qiita.com/YamadaGames/items/cde2162b52ba80bc0beb

他のオブジェクトとの衝突などを考慮する場合には、~~transform.position の変更よりも transform.Translate や ~~ Rigidbody の各種メソッドを使うほうが確実、ということのようです。
(※ sakura_hana さんの指摘を受けて一部訂正しました)

上記の記事内で、Time.deltaTime を掛けることについてもコメント含めて記述があります。Update() メソッドはプログラムを動作させる環境によって1秒間あたりに呼び出される回数が異なるため、その差異を吸収するためには Time.deltaTime を掛けるのが有効なようです。

どういうものなのかを理解した上で使い分ける、というのがよいのだと思います。

投稿2018/06/08 10:07

編集2018/06/08 11:32
negitama

総合スコア943

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

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

sakura_hana

2018/06/08 11:27

横から失礼します。 transform.Translateも物理演算を引き起こさないので衝突するオブジェクトに使うのは危険です。 リンク先の画像で跳ね返っているのは、移動速度が遅い為に「衝突を無視して壁に埋まる→移動が終了した瞬間に物理演算発動→壁からはじき出される」という動きです。
negitama

2018/06/08 11:28

なるほど、正確な解説ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/06/08 11:43 編集

ご回答ありがとうございます。また、sakura_hana様もご指摘とご解説ありがとうございます。 衝突を考慮するならば、そもそもtransform系の移動が非推奨ということなんですね。 Rigidbodyでの移動は一定の速度でないと思い込んでいましたが、velocityで設定するのであれば、 一定速度で移動できるみたいですね。
sakura_hana

2018/06/08 11:51

> Rigidbodyでの移動は一定の速度でない velocityで設定する他、(こちらも厳密に試していませんが)摩擦・重力ゼロにしてAddForceした場合も慣性の法則で一定速度で動き続けるんじゃないかなーと思います。 第二引数の指定によって普通の加速(徐々に力が込められる)か瞬時に最高速に達するか変えられたりもします。 http://d.hatena.ne.jp/nakamura001/20120320/1332224186
negitama

2018/06/08 12:04

> tkmnusr さん 物理演算をUnityに頼るなら、移動にもRigidbodyを使うのが便利だよという話だと思います。私の回答が原因で話が発散してしまったかも。 なおRigidbodyのvelocityの値を直接いじるのも若干注意が必要なようで、理解した上で使い分けるのがよさそうです。 https://docs.unity3d.com/ja/current/ScriptReference/Rigidbody-velocity.html (Unity公式の Space Shooter tutorial などでも velocity を直接変更しているので、絶対ダメというわけではないのでしょう) 移動処理は突き詰めるとなかなか難しいですね。。。 個人的にはカメラやUI要素の移動などで物理演算を必要としないものにはTransform.position の値変更や Transform.Translate を使っていますが(そのときの用途で使いやすいほうを選択)、アクションゲームのプレイヤーキャラクターなどはRigidbodyを使って動かすことが多いです。
退会済みユーザー

退会済みユーザー

2018/06/08 13:10

ご回答ありがとうございます。 ご提示のページ拝見しました。 なるほど、非現実的という意味では、直接いじるべきではないということですね。 今回自分は、入力してから瞬時に一定の速度で移動させることが目的だったので(transform系のような動きの移動)、直接velocityをいじる方法が、物理演算による衝突も加味された上で一定速度で移動できるので、ベストな方法だと理解できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問