【Unity】RigidbodyのIsKinematic(物理演算の影響の有無)を変えて実験
- 2018.05.15
- Rigidbody
- IsKinematic, Rigidbody, Unity
Rigidbodyコンポーネントの中で、特に分かりにくい設定がIsKinematic。
このRigidbodyがアタッチされているオブジェクトが、物理演算の影響を受けるかどうかを定義しています。
うん。……うん?
物理演算をさせるためのRigidbodyなのに、物理演算をさせないようにする設定って、どういうこと?
となるIsKinematicさんについて解説しつつ動きの実験をします。
環境
macOS 10.13 High Sierra
Unity2018.1.0f2
4月末にUnity2018が出てたので早速使ってみました。
Rigidbodyについて
Rigidbodyのアタッチ方法や各設定項目の説明は、以下の記事で解説しています。
ざっくり言うと、Unityで物理演算を使うために必要なコンポーネントです。
今回はその中でもIsKinematic(物理演算の影響の有無)がテーマ。
IsKinematic(物理演算の影響の有無)について
初見でこの設定の意味を理解できたら多分Unity界の麒麟児です。
私は全く意味が分かっていませんでした。
UnityのスクリプトリファレンスではisKinematicについて、
物理演算の影響を受けるかどうか
と書かれています。じゃあtrueなら物理演算の影響を受けるのかな? なんて思ってしまうと真逆の結果になって混乱する罠。
実態としては、trueなら物理演算の影響を受けない、falseなら物理演算の影響を受けるのが正しい動き。
翻訳文に惑わされますね。なので元々のIsKinematicの言葉から出発するといいかも。
『Kinematic』という言葉自体も馴染みがありませんが、日本語訳すれば「運動学的な」という意味になります。
……運動学ってなんやねん。スポーツ医学的なアレなのか!?
とさらに混乱したところで、お次は『運動学』自体も辞書で調べてみましょ。
運動学とは物理における力学の一分野で、物体の運動に関して力の詳細にまでは触れず、位置の移動やその時間変化など、数学的に記述する分野のこと。
そう言えば、高校物理の一番最初は、変位やら速度やら加速度のお話でした。あの辺のことですね。
ポイントは、力の詳細に触れない点です。
Unity的に言えば、AddForceや重力の影響を受けないということ。
なのでスクリプトからTransformを直接いじって、物体の位置を決めてあげる必要があります。
つまり、IsKinematicをtrueにした場合は、スクリプトからオブジェクトの位置を設定しますぜ旦那、という宣言なのでした。
だからIsKinematicをtrueにすると力が働かないんですね。
IsKinematicを使うメリット
Unityのマニュアル内、『Rigidbody概要』には、「Rigidbodyを使うときはTransformの値をいじらないでね」と書かれています。
じゃあなんでこの設定があるの? なんて思っていたら、英語の部分で「でも物理的な挙動じゃない動きをさせたい時もあるよね。そんなときはIsKinematicを使ってね」とありました。
物理的な挙動じゃなければ、それこそRigidbodyいらないんじゃ……?
と初心者の頃の私は思ってしまったのですが、Colliderで衝突を検知するために必要だったり、動的にIsKinematicを切り替えることができたりと、結構メリットがあるんです。
マニュアルのColliderの項目にある例だと、ドアをスライドさせるケースが分かりやすかったです。
通常、ドアが閉まっている時にはキャラクターとの衝突を可能にし、通さないようにしなければなりません。
キャラクターが開けるアクションを取った時には、スクリプトからドアを決められた位置にスライドさせ、通れるようにします。物理挙動では、下手したらドアが吹き飛んだりすることもありますし、決まった位置まで移動させるのはちょっと調整が大変。
また、ドアの開け閉めの時だけIsKinematicに切り替えるようにすれば、開けるアクションを取ればIsKinematicにして位置を制御、武器でドアを攻撃したらRigidbodyのまま吹き飛ぶ、なんて実装も可能になります。
これらを考えると、ドアは単にRigidbodyとして扱うより、キネマティックなRigidbodyとして扱った方が制御しやすいんです。
転がる時のIsKinematic
さて、値を変えた時の運動の様子を観察してみましょ。
まずはボールを転がすところから。
用意したボールは以下の2種類。
- isKinematic : true
- isKinematic : false
これらのボールに、同時に力を与えた時の運動を観察します。
ForceModeはImpulseとし、加えた力の大きさは画面左上に表示しています。
物理演算の影響を受けないだけあって、IsKinematicがtrueだと一切動きませんね。
斜方投射でのIsKinematic
一応斜方投射でも確認してみます。
まあ、そうなるな。
転がる時と同様に、IsKinematicがtrueであればAddForceしても知らんぷり。
自由落下の場合
もはや結果は分かりきっているような気もしますが、自由落下も確認。
ですよねー。
IsKinematicがtrueなら、重力の影響すら振り切ります。
なお、左のオブジェクトのRigidbodyでは、UseGravity(重力の使用)をtrueにしてありますが、IsKinematicの方が優先されていますね。
動的にIsKinematicを切り替える場合はUseGravityの外し忘れなどに注意。
動的にIsKinematicを切り替える
IsKinematicの切り替えの例として、ボールが衝突してきたら1秒後にスクリプトによる運動に切り替える機能を実装してみました。
Rigidbodyの特性を活かすため、IsKinematicがfalseの間は通常の衝突をするようにしています。massに差を付けているので、ボールの吹き飛び方にも差異があります。
画面右からピンク色のボールが衝突すると、1秒後に白と黄色のボールがIsKinematicをtrueにして往復運動を開始します。この動作はスクリプトからTransformを直接操作しています。
手前のピンクのボールは衝突相手のmassが大きいために、反対まで転がって往復運動の範囲外まで逃げていますが、奥のボールは何度も襲われています。かわいそう。
実のところ、奥のボールは白いボールが接触した時に右に大きく吹き飛ぶイメージだったのですが、そうではないのですね。
と思って、今度はCubeを使って衝突を観察。すると、IsKinematicになった後にもピンクのボールに力を与えていることが分かります。
相変わらず手前は逃げるのが早いですね。
奥のボールはうまく押してもらってるので、ダンジョン内の動く壁として実装し、キャラクターを奈落の底に叩き落とそうとする仕掛けとかに使えそう。
でもって、その動く壁はキャラクターよりもある程度大きくしておいた方が良さそう。上の画像で、衝突するボール同士が同じ大きさだと、Rigidbodyの方が変な動きしてますもんね。
オブジェクトの動きをスクリプトから制御したい場面は結構多いと思うので、うまく切り替えを入れられるといい感じ。
まとめ
初心者にとっての難敵、RigidbodyのIsKinematicを使った実験でした。
最初は使い道が難しいかもしれませんが、スクリプトからオブジェクトの動きを制御する場面が結構あるため、実は便利な機能なんです。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】RigidbodyのUseGravity(重力の使用)を変えて実験 2018.05.15
-
次の記事
Unity2018でFixedTimestepのデフォルト値が変わったのね 2018.05.16
[…] 【Unity】RigidbodyのIsKinematic(物理演算の影響の有無)を変えて実験 […]