0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

直接の親子関係無しで「動く足場」の上の物体を制御する

Last updated at Posted at 2021-08-07

動く足場の上に乗った物体を足場と一緒に動かしたい場合、足場のオブジェクトと親子関係にするのが定番だが、親子関係にすると不都合が出る場合がある。
たとえば、CharacterControllerで制御しているプレイヤーを動くオブジェクトの子供にすると、CharacterControllerの動作が怪しくなることなどがあった。

そのような場合に、なるべく簡単かつ軽量に同様の処理を実装したい。

前提として
・「足場」は次frameでどのように移動できるか予測できない
・「上に乗っている物体」は、足場の上で好きに動く(乗り物の上にいる操作キャラのように)
のような状態でも使える方法とする。

実装1:計算でゴリ押し実装
親子関係で無い以上、LateUpdate()内で、動く足場が前フレームの位置からどれだけ移動したか?どれだけ回転したか?を確認する方法になるが、ややこしい計算になる。
「平行移動」については、足場のposition変化量を物体のpositionに加算するだけで良いが、足場のrotationについては、足場の回転軸と物体の位置関係も考慮する必要がある。
Vector3系関数を使って計算する場合、お互いのlossyScaleに影響しないように考慮が必要な場合もある。

一応はそれっぽく動いたが、複雑な計算だと分かりづらく、意図的にイレギュラーな動きをさせたい場合などに応用が難しそうだったため、もっと簡単な方法を模索

実装2:目印オブジェクトを使う
動く足場の子オブジェクトとして、目印のオブジェクトを用意する。RigidbodyもColliderもRendererも無いEmptyオブジェクトで良い。

動く足場に乗った物体ごとに1つずつの目印を用意する

LateUpdate()内でやることは、
①目印のpositionが前フレームの目印のpositionと異なる場合
 ②物体のposition += 目印のposition - 前フレームの目印のposition
 ③目印のposition = 物体のposition
 ④目印のpositionを変数に格納(次フレームに①②で利用)
⑤目印のrotationがQuaternion(0f, 0f, 0f, 1f)と異なる場合
 ⑥物体のrotation = 物体のrotation * 目印のrotation
 ⑦目印のrotation = Quaternion(0f, 0f, 0f, 1f)

つまり、目印のrotationを毎フレーム「物体の座標」、「固定の方向」に合わせておく。
目印は足場の子オブジェクトなので、「物体が子オブジェクトだったらどれだけ動くか?」をトレースしてくれる。なので、次フレームでは物体の座標を「目印の座標変化量」だけ移動させ、物体の回転を「目印の回転」だけ回転させるだけ。

工夫したところは、前フレームの目印のrotationを覚えておいたり、物体のrotationと合わせたりしなくても、毎フレームQuaternion(0f, 0f, 0f, 1f)で固定しておけば、次フレームで変化分を簡単に反映できるところ。

処理がシンプルなので、「足場の動きの変化にあわせて揺らしたい」「移動や回転速度が一定以上になると追従を弱めたい」「足場から離れた時の慣性の計算に使いたい」ような場合にも工夫しやすい。

毎フレームの計算になるので、目印と物体のtransformを変数に入れておくこと。Quaternion(0f, 0f, 0f, 1f)も事前にnewで作って使い回すことを忘れずに。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?