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

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

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

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

Q&A

解決済

1回答

2005閲覧

ワールド軸の向きと一致させないときのAtan2

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2019/02/22 16:37

前提・実現したいこと

ワールドの上から見下ろすように、ZX平面で、ZをtanのYとみなし、XはそのままtanのXと考えた場合、

C#

1 Vector3 dt = sphere.transform.position - this.transform.position; 2 Debug.Log(Mathf.Atan2(dt.z, dt.x));

で、意図したAtan2が取得できることはわかりましたが、
この状態で、オブジェクトのY軸を回転させたとき、そのオブジェクトの軸を基準としたAtan2は、
どのようにすれば取得できるかご教示お願いします。

試したこと

イメージ説明

図において、キューブの軸と位置を基準に、球となすAtan2の取得を考えています。
キューブと球を原点に配置し、両方ともY軸で45度回転させて、
球だけ球のX軸方向に移動させました(キューブのX軸上に移動させました)。
そこで、上記コードを実行してみたのですが、
意図した通りにAtan2が取得できれば、その値は0になると想定していたのですが、
実際は、「-0.7853982」という値が取得されたので、上記コードではダメらしいということはわかりました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

球のワールド座標をInverseTransformPointでキューブを基準とした座標系に変換してやればよさそうですね。

C#

1using UnityEngine; 2 3public class WorldAndLocalAtan2 : MonoBehaviour 4{ 5 [SerializeField] private GameObject sphere; 6 7 private void Start() 8 { 9 // ベクトルがワールド座標系を基準としていれば... 10 var worldDt = this.sphere.transform.position - this.transform.position; 11 Debug.Log($"Cube world position : {this.transform.position.ToString("G")}"); 12 Debug.Log($"Sphere world position : {this.sphere.transform.position.ToString("G")}"); 13 14 // 得られる角度もワールド座標の軸を基準にしたものになるでしょう 15 Debug.Log($"World Atan2 : {Mathf.Atan2(worldDt.z, worldDt.x)}"); 16 17 // 両オブジェクトのワールド座標をキューブのローカル座標系での座標に直すと... 18 var cubeLocalPosition = this.transform.InverseTransformPoint(this.transform.position); 19 var sphereLocalPosition = this.transform.InverseTransformPoint(this.sphere.transform.position); 20 var localDt = sphereLocalPosition - cubeLocalPosition; 21 Debug.Log($"Cube local position : {cubeLocalPosition.ToString("G")}"); 22 Debug.Log($"Sphere local position : {sphereLocalPosition.ToString("G")}"); 23 24 // 得られる角度はキューブの軸を基準にしたものになるでしょう 25 Debug.Log($"Local Atan2 : {Mathf.Atan2(localDt.z, localDt.x)}"); 26 27 // なお、cubeLocalPositionはキューブローカル座標の原点であり、常に(0, 0, 0)になるはずです 28 // そのため、わざわざ2つの座標の差を求めずとも、sphereLocalPositionがそのまま 29 // キューブに対する球の相対的位置を表しているので、下記でもいいでしょう 30 Debug.Log($"Local Atan2 : {Mathf.Atan2(sphereLocalPosition.z, sphereLocalPosition.x)}"); 31 } 32}

結果

計算誤差によりsphereLocalPosition.zに小さな値が入ってしまい、Atan2がぴったり0にはなりませんでしたが、おおむね0になりました。

投稿2019/02/22 22:18

Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2019/02/23 04:26

ご回答ありがとうございます。 InverseTransformPointというメソッドがあるのですね。 念の為、確認させていただきたいのですが、 Vector3 objBLocalPosition = objA.transform.InverseTransformPoint(objB.transform.position); とすると、objBの座標を、objAのローカル座標で取得できるということですね? あと、横道にそれてしまいますが、 ToString("G")というふうに、Gを引数にすると、Vector3の文字列に変換してくれるということですか? 他にどんな引数を与えることができるのか知りたく、ToStringの引数に関するドキュメントや資料があれば、教えていただけませんか?
Bongo

2019/02/23 10:18

はい、InverseTransformPointについてはそういうことです。 ToStringについてですが、まずDebug.LogにVector3(仮にvとします)をそのまま渡した場合はDebug.Log(v.ToString())としたのと同じ結果になります。文字列にするには別にToStringに引数を与えなくてもいいのですが、それだと各成分がいつもの小数点以下1桁...「(5.7, 0.0, 0.0)」のような形になってしまいます(v.ToString("F1")としたのと同じ文字列になります)。今回はZ成分に小さな誤差が生じていることを示したかったため"G"を使いました。これにより、各成分のfloatを文字列化するときに書式として"G"が使われるので、自動的に小数点以下の桁数が変わったり、指数表示になったりするわけです(floatをDebug.Logで表示したときのような感じですね)。 書式指定はUnityに限ったものではありませんので、詳細はC#、.NET全般に関する解説サイトを探してみるのがいいかと思います。「文字列の書式設定 - クラスライブラリ | ++C++; // 未確認飛行 C」(https://ufcpp.net/study/dotnet/bcl_format.html )ですとか、「.NET での型の書式設定 | Microsoft Docs」(https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/formatting-types )などがご参考になるかと思います。
退会済みユーザー

退会済みユーザー

2019/02/23 17:09

ご回答ありがとうございます。 InverseTransformPointのご回答ありがとうございます。理解できました。 Vector3は、引数無しのToString()でも、各成分を出力してくれるのですね。 知りませんでした。試して確認しました。 なるほど、Vector3の各成分について細かい小数まで出力するには"G"を付けるということだったのですね。URLのご提示ありがとうございます。確認致しました。 とても勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問