回答編集履歴
1
Quaternion方式の例を追記
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`をもっと大きくしてやるのがいいかと思います。
|