回答編集履歴

1

Quaternion方式の例を追記

2019/07/21 15:45

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -81,3 +81,45 @@
81
81
  **余談**
82
82
 
83
83
  あの姿勢復元コードの投稿後に検索してみたのですが、[【Unite Tokyo 2018】誘導ミサイル完全マスター](https://youtu.be/t_4MbV2zIwg?t=713)の講演で紹介されている「現在の姿勢から目標の姿勢への回転を表すQuaternionを得て、そのxyz成分に比例したトルクを加える」という案の方がエレガントでよさそうですね。xyz成分の向きはまさしく回転軸の方を向いていますし、大きさは「角度差÷2」のサインに比例しています。トルクの大きさが角度差0°~180°まで単調増加するので、より一層バネっぽくなりそうです。またQuaternionの計算にUnityの提供する各種メソッドがそのまま利用できるため、コードも簡潔になってわかりやすいでしょう。[【Unite 2017 Tokyo】スマートフォンでどこまでできる?3Dゲームをぐりぐり動かすテクニック講座](https://youtu.be/6EtTI5xC524?t=1930)では実演しながら解説されており、非常にご参考になるかと思います。
84
+
85
+
86
+
87
+ **追記**
88
+
89
+ 現状だと機体の現在の回転とそれの逆回転をかけてしまっており、得られるクォータニオンが無回転になっているようです。
90
+
91
+ 後ほどじっくり講演を見直していただきたいのですが、トルク源として用いるべき回転は「現在の姿勢から目標の姿勢への相対回転」となります。現在の姿勢は`transform.rotation`、目標姿勢は`Quaternion.identity`です。ですので、講演の式に当てはめると`Quaternion.identity * Quaternion.Inverse(transform.rotation)`ということになりますね。
92
+
93
+ もっと単純に言うと、無回転から`transform.rotation`だけ回転すれば現在の姿勢になるのですから、現在の姿勢から無回転に戻す回転はそれの逆回転...`Quaternion.Inverse(transform.rotation)`です。
94
+
95
+
96
+
97
+ ```C#
98
+
99
+ Quaternion rot = Quaternion.Inverse(transform.rotation);
100
+
101
+ if (rot.w < 0f) {
102
+
103
+ rot.x = -rot.x;
104
+
105
+ rot.y = -rot.y;
106
+
107
+ rot.z = -rot.z;
108
+
109
+ rot.w = -rot.w;
110
+
111
+ }
112
+
113
+ Vector3 restoringTorque = new Vector3(rot.x, rot.y, rot.z) * restoringTorqueMagnitude;
114
+
115
+
116
+
117
+ // 機体にトルクを加える
118
+
119
+ rigidbody.AddTorque(rotationTorque + restoringTorque);
120
+
121
+ ```
122
+
123
+
124
+
125
+ 補足しますと、この方式に書き換えると復元トルクの大きさが小さめに(バネがやわらかく)なりますので、それに応じて`restoringTorqueMagnitude`をもっと大きくしてやるのがいいかと思います。