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

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

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

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

Q&A

解決済

1回答

5026閲覧

ベクトルの向きを指定したベクトルと同じ向きに設定する方法

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2020/10/10 15:03

編集2020/10/10 15:04

前提・実現したいこと

自身のゲームオブジェクトの正面方向(自身のゲームオブジェクトのZ軸方向)を、指定したベクトルの向きに設定したいのですが、
その方法は以下2つの方法になりますか?
以下2つのコードは同じ処理でしょうか?
ご教示お願い致します。

C#

1 Vector3 direction = target.transform.position - this.transform.position; 2 this.transform.forward = direction;

C#

1 Vector3 direction = target.transform.position - this.transform.position; 2 this.transform.localRotation = Quaternion.LookRotation(direction);

また、これら以外にも方法があればご教示お願いします。

試したこと

こちらのサイトこちらのサイトを参考にしました。
実際に上記質問コードで、2つのオブジェクトを用意して試したところ、どちらも同じ方向を向いているように見えました。
また、それぞれで下記デバッグをとったところ、同じベクトルとなっていました。

C#

1Debug.Log(this.transform.forward);

しかし、LookRotationのリファレンスを見てみると、

C#

1public static Quaternion LookRotation (Vector3 forward, Vector3 upwards= Vector3.up);

と第2引数で、上方向を定義するベクトルが用意されていたので、
「this.transform.forward = direction;」で向かせる方法とは異なるのかなと思いました。
考えてみれば、自身のゲームオブジェクトのZ軸方向を、指定したベクトルと同じにすると言っても、
そのときの自身のゲームオブジェクトのY軸方向は何通りも考えられるので、
単純に自身のゲームオブジェクトの正面方向(Z軸方向)を指定したベクトルに設定するだけならば、何通りもあるということでしょうか?
そう考えると、普通は自身のゲームオブジェクトの上方向(Y軸方向)も考慮した上で、
自身のゲームオブジェクトの正面方向(Z軸方向)を指定したベクトルに設定したいことが多いと思うので、

C#

1 Vector3 direction = target.transform.position - this.transform.position; 2 this.transform.localRotation = Quaternion.LookRotation(direction);

の方法で、設定することが適切ということでしょうか?

C#

1 Vector3 direction = target.transform.position - this.transform.position; 2 this.transform.forward = direction;

の方法では上方向は考慮されていないですよね?(これに上方向を考慮する方法はありますか?)

なお、今回の質問では、やりたいこととして、与えられたベクトルと同じ向きにすることを考えているので、
与えられた地点に向かせること(LookAtメソッドを使うようなこと)は考えていません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Quaternion.LookRotationによる方法は、求まった回転をrotationにセットするのであればTransform.forwardへの方向セットと同等と言えるでしょう。
UnityCsReference/Transform.bindings.cs at master · Unity-Technologies/UnityCsReference · GitHubによると...

C#

1 // The blue axis of the transform in world space. 2 public Vector3 forward { get { return rotation * Vector3.forward; } set { rotation = Quaternion.LookRotation(value); } }

となっており、forwardへのセットの際にはQuaternion.LookRotationが使われていることを見て取れるかと思います。

念のため申し上げますと、ご質問者さんの例示されたコードではQuaternion.LookRotationの結果をlocalRotationにセットしていますので、もしセット対象のオブジェクトに親オブジェクトが存在するのなら、それらの姿勢は無回転でないと結果が一致しなくなるだろうとは思われますが...

おっしゃる通りQuaternion.LookRotationには第2引数として上方向を指定することができますが、上記で引用したTransform.forwardでは第2引数なしのバージョンが使われていますので、上方向指定はできないでしょうね。ですが、普通のゲームでしたら上方向はデフォルトのY軸上向きで問題ないでしょうから、Quaternion.LookRotationによる方法でもTransform.forwardによる方法でもどちらでもかまわないだろうと思います。
もしスーパーマリオギャラクシーみたいに上方向を決め打ちできないゲームを作るおつもりでしたら、上方向を適切に与えてやらねばなりませんのでQuaternion.LookRotationによる方法を使うことになるでしょう。

また、これら以外の方法となると、さしあたり思いつくのはTransform.LookAtによる方法(今回はご質問者さんはLookAtを使うつもりはないご様子ですが)とか、あるいは...

C#

1 Vector3 direction = target.transform.position - this.transform.position; 2 this.transform.rotation = Quaternion.FromToRotation(Vector3.forward, direction);

というのもあり得るでしょう。これは先に引用したTransformの実装の...

C#

1 // The red axis of the transform in world space. 2 public Vector3 right { get { return rotation * Vector3.right; } set { rotation = Quaternion.FromToRotation(Vector3.right, value); } } 3 4 // The green axis of the transform in world space. 5 public Vector3 up { get { return rotation * Vector3.up; } set { rotation = Quaternion.FromToRotation(Vector3.up, value); } }

と同様の形ということになります。Quaternion.FromToRotationはあるベクトルを別のベクトルへ向ける最短の回転を求めますので、回転後の上方向がワールド空間の上方向になるとは限りません。うまく使えば空間中を自由に飛び回るミサイルなどの制御を自然に表現できるかもしれませんが、人型キャラクターでは頭の向きが地面に対して傾いてしまうでしょうから使いにくいような気がしますね。

投稿2020/10/10 22:58

Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2020/10/11 04:35

ご回答ありがとうございます。 念の為、確認させていただきたいのですが、下記2行が同じコードということになりますか? this.transform.forward = direction; this.transform.rotation = Quaternion.LookRotation(direction); transform.forwardも内部で第2引数を省略したLookRotationが使われていたのですね。 つまり、上記2行は上方向をVector3.upと定義した上で、 自身のゲームオブジェクトの正面方向(Z軸方向)を第1引数のベクトルの向きに設定するコードということで合っていますか? そして、上方向をVector3.up以外のベクトルで定義したい場合は、 transform.forwardではその方法がなく、LookRotationで設定するしか方法がないということですね。 LookAtに関してですが、そうですね、今回の質問例では、 Vector3 direction = target.transform.position - this.transform.position; として目的の地点も明確にしていますが、 実際は、今回やりたいこととして、他の方向ベクトルをdirectionとして与えることを考えているので、 地点ではなく、方向ベクトルが与えられることを前提として、そのベクトルの向きに設定することを 考えているので、今回はLookAtの使用を考えていないです。 LookAtのリファレンスも見ましたが、念のためお訊きしたいのですが、 LookAtでは、方向ベクトルが与えられても、その方向ベクトルの向きに設定する方法はないですよね? forwardでは内部でLookRotationが使われているけど、rightやupでは、内部でFromToRotationが使われていたのですね。 危うくrightやupでもLookRotationが使われていると思い込むところでした、ありがとうございます。 なるほど、Quaternion.FromToRotationは上方向を考慮しないで最短で回転するのですね。 Quaternion.FromToRotationもよくわかっていなかったのでとても勉強になります。
Bongo

2020/10/11 06:27

はい、前半のLookRotationに関するコメントはその通りかと思います。 LookAtに関しては、おっしゃる通り引数として受け取るのはワールド座標ですので、ある方向ベクトルの向きに向けたい場合は... this.transform.LookAt(this.transform.position + direction); といった形で使う必要があるでしょうね。
退会済みユーザー

退会済みユーザー

2020/10/11 06:40

ご回答ありがとうございます。 なるほど、LookAtでも、this.transform.position + directionとすれば、方向ベクトルで表現できたのですね。勉強になります。 全ての疑問が解決しました。 ご教示いただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問