読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】アニメーションと物理演算を連動させる

f:id:tsubaki_t1:20161017225314g:plain

試したら出来てしまったので、一応メモします。

 

物理演算とアニメーション

Unityを初めて作った人がよくやる事が、物理演算ベースで作成したキャラクターをアニメーションで動く床に載せるというステージ構成です。

これは一見上手く動きそうに見えますが、実際にはうまく動作しません。これは、Animationによるオブジェクトの移動とPhysicsによる移動が異なる事が問題です。

f:id:tsubaki_t1:20161017231808g:plain

 

物理演算でオブジェクトを動かす場合、オブジェクトは数学の時間に学んだような演算でもって動きます。また、数学の時間に学んだような演算で、他の物理オブジェクトに対して影響を与えます。

f:id:tsubaki_t1:20161017231151g:plain

 

アニメーションで動くオブジェクトは、基本的にキーフレームが指定する位置に「テレポート」しています。その過程での加速度や質量等の情報は一切持っておらず、また他の物理オブジェクトに運動エネルギーを与える事は無いです。

f:id:tsubaki_t1:20161017225000j:plain

 

Animationで動かしている床や壁は物理演算で動いていないので、摩擦係数や質量をいくら重くしても、物理演算で動作しているオブジェクトに影響を与える事は無い訳です。(当たり判定は影響します。また、めり込んだ場合は吹き飛ばす事があります)

 

Animationに物理演算の力を追加

Animationで動作するオブジェクトに物理演算の効果を与えるのは無理かなーと個人的には思ってましたが、ふと思いついて試してみたら上手くいきました。

 

今回やる事は単純で、ColliderとRigidbodyの付いているオブジェクトを、Animationで動作するFIxedJointで引っ張るという物です。
Animationはワープですが、それをFixedJointで引っ張る事で、一応物理的に動いている扱いにする…という物です。ぶつかっても反動が無く質量はほぼ無限大扱いなので、ぶつける等では変な挙動になるかもしれませんが、まぁとりあえず動きます。

 

実際にやってみる

まずAnimationで地面の動きを用意します。
今回は、Z軸に移動します。

f:id:tsubaki_t1:20161017230817g:plain

 

次に、JointでPlaneを引っ張ります。
まずはPlaneが引っ張れるように、Planeに物理演算を追加します。その際、Use Gravityは外しておきます。

f:id:tsubaki_t1:20161017231409j:plain

 

次に引っ張るJointの設定です。こちらは色々と設定する事があります。

まずAnimatorのUpdateModeをAnimatePhysicsに設定します。こうしないと、摩擦で動くときに少しカクカクします。

また、Animationで動くオブジェクトには物理演算による動きは不要なので、IsKinematicをRigidbodyに設定します。

あとはFixedJointを追加して、引っ張る対象にPlaneを設定します。

f:id:tsubaki_t1:20161017231532j:plain

 

これで再生すると、Animationの動きに沿ってPlaneが動きます。
動かない場合、Jointが動いていないか、FixedJointを指定してないか、もしくはPlaneにIsKinematicが付いてます。

また、これで動かすPlaneには物理演算が付いているので、上に載っている物も追随する形で動いてくれます。

f:id:tsubaki_t1:20161017232614g:plain

 

Physics2Dでは少し手法が異なる

Physics2Dの場合、設定が少し異なります。

その辺りはまた今度

f:id:tsubaki_t1:20161018003259g:plain


 

 関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp