🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

4826閲覧

[Unity] オブジェクトのRotationの値を変化させたときの挙動について質問

daidaiiro

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

1クリップ

投稿2019/07/15 07:59

Unity の2018.3.14f1 を利用しています。

Unityの3D環境でオブジェクトを回転させようとしていますが、
オブジェクトのRotateの仕組みがよくわかりません。

シーンにプリミティブのSphereを1つ置き、
オブジェクトのX軸の角度を確認するため以下のコードをコンポーネントとして加えました。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class CheckAngle : MonoBehaviour 6{ 7 // Update is called once per frame 8 void Update() 9 { 10 Debug.Log("eular angle : " + this.transform..rotation.eulerAngles.x); 11 } 12} 13

次にPlayボタンを押し起動させ、Unityエディタ上でRotationのXに直接値を入力し、
Debug.Log から吐き出されるログを確認したところ、以下のような値になりました。

Editer 上の値ログの値
00
3030
6060
9090
12060
15030
1800
210330
240300
270270
300300
330330
3600

エディタ上では90度を超えるとログの値が下がり、180度を超えると急に360度になり、やはり下がり続けます。
さらにエディタ上の値が270を超えると逆に上がり、360度を超えると0に戻ります。
これはどうとらえたら良いのでしょうか?
よくわかりません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

スクリプトから取得したオイラー角についてXだけでなくY、Zも観察していただきますと、姿勢によってはいきなり180°回転したりする様子を見ることができるかと思います。
下記のようなコードを実行してみましたら...

C#

1using System; 2using System.Collections; 3using UnityEngine; 4 5public class PrintRotation : MonoBehaviour 6{ 7 private float angle; 8 9 private IEnumerator Start() 10 { 11 var interval = new WaitForSeconds(0.1f); 12 while (true) 13 { 14 yield return interval; 15 16 this.angle += 1.0f; 17 var inputAngles = new Vector3(this.angle, 0.0f, 0.0f); 18 transform.eulerAngles = inputAngles; 19 var resultAngles = transform.eulerAngles; 20 Debug.Log($"Input : {inputAngles}, Result:{resultAngles}"); 21 } 22 } 23 24 private void OnGUI() 25 { 26 var eulerAngles = transform.eulerAngles; 27 GUILayout.Label($"A {this.angle:F0}"); 28 GUILayout.Label($"X {eulerAngles.x:F0}"); 29 GUILayout.Label($"Y {eulerAngles.y:F0}"); 30 GUILayout.Label($"Z {eulerAngles.z:F0}"); 31 } 32}

下図のように途中からY、Zがひっくり返ってXが減少に転じ、さらに回転を続けるとまたY、Zがひっくり返り、Xが再び増加し始める様子が撮影できました。

結果

たとえば入力値として(135, 0, 0)を与えると、それを再び取り出したときには(45, 180, 180)に変わっています。ですが、3D空間上の姿勢はどちらも同じになっている様子がお分かりいただけますでしょうか?

Transform-eulerAngles - Unity スクリプトリファレンスに注釈があるように...

Do not set one of the eulerAngles axis separately (eg. eulerAngles.x = 10; ) since this will lead to drift and undesired rotations. When setting them to a new value set them all at once as shown above. Unity will convert the angles to and from the rotation stored in Transform.rotation.

eulerAnglesの軸の一つだけを個別に設定(たとえばeulerAngles.x = 10;)するのは値のドリフトや意図しない回転につながりますので避けてください。上に示したように、新しい値を設定するときはすべての軸を一度に設定します。Unityは角度を回転に変換してTransform.rotationに格納、あるいはTransform.rotationの回転を角度に変換して取り出します。

このような挙動は、回転の表現形式としてQuaternionが使われる都合上しかたないところがありますので、X軸周りの連続した角度が欲しい場合は自前でオイラー角状態のまま(Quaternion型を経由させずに)角度を持っておくか、あるいは独自に計算する必要があるかと思います。
インスペクター上の角度表示ではこのような一見奇妙な動きは起こりませんが、これは内部的にQuaternionに変換されていないオイラー角も一緒に保存しているためのようです(エディタスクリプトではこの生の角度にアクセスすることもできなくはなさそうですが、ゲーム実行時には無理かと思います。)。

投稿2019/07/15 13:17

Bongo

総合スコア10811

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

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

daidaiiro

2019/07/15 14:53

なるほど、よくわかりました。x,y,z 全てを見ると辻褄があっているのですね。 コード、実行時の動画を提示していただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問