teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

Quaternion方式の例を追記

2019/07/21 15:45

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -39,4 +39,25 @@
39
39
  の形が出てきます。これに`restoringTorqueMagnitude`をかけて大きさを調整したものを使いました。
40
40
 
41
41
  **余談**
42
- あの姿勢復元コードの投稿後に検索してみたのですが、[【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)では実演しながら解説されており、非常にご参考になるかと思います。
42
+ あの姿勢復元コードの投稿後に検索してみたのですが、[【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)では実演しながら解説されており、非常にご参考になるかと思います。
43
+
44
+ **追記**
45
+ 現状だと機体の現在の回転とそれの逆回転をかけてしまっており、得られるクォータニオンが無回転になっているようです。
46
+ 後ほどじっくり講演を見直していただきたいのですが、トルク源として用いるべき回転は「現在の姿勢から目標の姿勢への相対回転」となります。現在の姿勢は`transform.rotation`、目標姿勢は`Quaternion.identity`です。ですので、講演の式に当てはめると`Quaternion.identity * Quaternion.Inverse(transform.rotation)`ということになりますね。
47
+ もっと単純に言うと、無回転から`transform.rotation`だけ回転すれば現在の姿勢になるのですから、現在の姿勢から無回転に戻す回転はそれの逆回転...`Quaternion.Inverse(transform.rotation)`です。
48
+
49
+ ```C#
50
+ Quaternion rot = Quaternion.Inverse(transform.rotation);
51
+ if (rot.w < 0f) {
52
+ rot.x = -rot.x;
53
+ rot.y = -rot.y;
54
+ rot.z = -rot.z;
55
+ rot.w = -rot.w;
56
+ }
57
+ Vector3 restoringTorque = new Vector3(rot.x, rot.y, rot.z) * restoringTorqueMagnitude;
58
+
59
+ // 機体にトルクを加える
60
+ rigidbody.AddTorque(rotationTorque + restoringTorque);
61
+ ```
62
+
63
+ 補足しますと、この方式に書き換えると復元トルクの大きさが小さめに(バネがやわらかく)なりますので、それに応じて`restoringTorqueMagnitude`をもっと大きくしてやるのがいいかと思います。