原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】範囲内の時間を制御・・・してるっぽく見せる(Rigidbody編)

Unity1Week

先週はunityroomの方でUnity1Weekが開催されていました。

unityroom.com

当初は私も微力ながら参加する予定だったのですが、前日からくしゃみが止まらくなる症状が出始め、かつ何故か腰が痛くなるという風邪なのか何なのかよく分からない体調不良に悩まされていた為、断腸の思いで断念させていただきました。


まぁ、unityroomに投稿される作品はUnity1Weekに限らず年々とレベルが高くなっていて、Tweeterなどで上げられている進捗報告の動画を観るたびにビックリしたり落ち込んだりすることも多く、仮に参加出来ていたとしても途中で挫折したかも、、、とか思ったり。参加された皆さん、お疲れ様でした。

 

時間を制御・・・してるっぽく見せる

さて、以前の記事で一定範囲内にあるオブジェクトに対して、あたかも時間を制御しているかのようにゆっくり動作させる、みたいなことをしたのですが、その時はDoTweenとAnimationのTimescale、Speedを変更する手法で実現していました。

www.karvan1230.com

しかし、オブジェクトを動かす手段はDoTweenやAnimation以外でも様々な手法があります。


特に最近では『Human Fall Flat』などが人気になったように物理演算によるオブジェクトの挙動を楽しむゲームも増えてきているので、オブジェクトの位置を直接制御するのではなく、オブジェクトに力を加えることで動かしていく方法も注目されてきています。


Unityで物理演算とえばRigidbody。
なので今回はRigidbodyでも同じようなことができないか探っていきたいと思います。

 

Rigidbodyを使って動かす

Rigidbodyを使ってオブジェクトを動かす場合はAddForceでオブジェクトに力を加えて動かします。AddForceでは力の大きさと、継続的な力、瞬間的な力、みたいな力の種類を選んで指定します。


今回は下図のようなモデルを用意しました。

f:id:Karvan:20191022165035p:plain

 

赤い弾にAddForceで横方向に瞬間的な力を加えます。
そして横に移動した赤い弾が球体内にいる間だけゆっくりと移動する処理を作ります。

 

弾が球体内にいるかどうかの判定は前回と同様にTriggerEnterとTriggerExitで判定するのですが、今回の場合はDoTweenの時のように赤い弾だけのTimescaleは変更できません。

また、継続的に力を加えるわけではないのでAddForceのパラメータを変更するわけにもいきません。では、どうするか・・・

赤い弾の速度を直接変更します。

 Rigidbodyではオブジェクトのmass(質量)とvelocity(速度)、angularVelocity(回転角速度)を参照&更新できるので、TriggerEnterでvelocity(速度)を遅くして、TriggerExitで元に戻してあげれば良いはずです。なんて単純な手法。

 

Rigidbody myBody;

void Start()
{
    // Rigidbodyの取得
    myBody = this.GetComponent<Rigidbody>();
}

private void OnTriggerEnter(Collider other)
{
    // 速度を遅くする
    myBody.velocity *= 0.2f;
}

private void OnTriggerExit(Collider other)
{
    // 速度を元に戻す
    myBody.velocity /= 0.2f;
}

 

オブジェクトが回転している場合はangularVelocityに対しても同じような処理を行います。また、OnTriggerExitで速度を元に戻したのに極端に速度が落ちている場合は、OnTriggerEnterでmass(質量)を軽く(=小さく)してOnTriggerExitで元に戻してあげればよい感じなります。

 では、実際の動作を見てください

f:id:Karvan:20191022165447g:plain

 

折角だから別の方法も考える

先程は速度を直接変更しましたが、折角Rigidbodyを使っているので別の手法も考えてみました。

次はこんなモデルを使います。

f:id:Karvan:20191022165733p:plain

 

上空にいるウサギはRigidbodyによって自由落下します。

このウサギに対して球体内にいる間だけ逆方向(=上方向)にAddForceで瞬間的な力を繰り返し加えます。要は抵抗を受けてゆっくり落ちるようにします。

Rigidbody myBody;

void Start()
{
    // Rigidbodyの取得
    myBody = this.GetComponent<Rigidbody>();
}

private void OnTriggerStay(Collider other)
{
    // 上方向に力を加える
    myBody.AddForce(0.7f * Vector3.up, ForceMode.Impulse);
}

 

OnTriggerStayはCollider内にいる間、絶えず呼ばれるのでその中でAddForceを行います。ただ、これだけだと球体から出た時に速度が元に戻らないので、先ほどと同じようにOnTriggerExitでRigidbodyの速度を早くします。

 

private void OnTriggerExit(Collider other)
{
    myBody.velocity /= 0.15f;
}

 

で、実際の動作はこんな感じになります。

f:id:Karvan:20191022170115g:plain

想定通り、落下するウサギにブレーキが掛ったような動作になりました。

これはこれで面白い動きかな、とは思うのですが、速度を直接変更する手法と比べた場合、逆方向の力の大きさとか、速度を戻す係数等はオブジェクトの質量や落下する距離によるので、本当にゲーム内で使う場合は繰り返し実行して調整する必要があります。ちょっと面倒ですね。


 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。