キャラクターコントローラーを使う人型3Dモデルをジャンプさせる(その1:重力を加える)

俺の作った剣太郎に
ジャンプさせたいんだけど
(名前付けてたんすか……!)


先日Magica Voxelでそれらしいステージを作ったはいいものの、ジョン剣太郎はジャンプできないので少しの段差も飛び越えることができない。それどころか落ちることもできない。


Unity世界で水平方向にのみ移動する剣太郎

3Dオブジェクトに重力を与えるには、とりあえずお決まりのRigidbody(リジドボディ)コンポーネントを付ければよい……と思ったがそうはいかないのがUnityさんの面倒くさい難しいところ。

発狂しそうになってたわ~
(また発狂っすか……!)


CharacterControllerとRigidbody&Colliderは相性がわるい

CharacterController(キャラクターコントローラー)は3Dオブジェクトを簡単に動かすコンポーネントなので、Collider(コライダー、当たり判定)も持っている。しかしこのコライダーはなんちゃってコライダーなので、Rigidbodyを与えても地面(Colliderを付けた平たいキューブ)を突き抜けてしまう。


地面にコライダーがあるにも関わらず突き抜けてしまう剣太郎。キャラコンにカプセルコライダー付いてるんじゃないんかい


カプセルコライダーのコンポーネントを加えると意味不明な動きをしてしまう剣太郎

この問題は長らくUnity初心者勢を苦しめてきたに違いない。ちょっと頭のいいプログラマーさんなら「キャラクターコントローラーを使わずに動かせヨ」という話になってしまうかも。それができないからキャラコン様に頼っているというのに……!

キャラコン使わないのは大変そうなので
キャラコンを使いつつ、
重力を発生させる方法を見つけておいた
そめ先生さすがっす!


重力を「下向きに引っ張られる力」と考えてみよう。「下向きに秒間9.8m/sずつ移動させる」というふうに考えるわけだ。通常、Rigidbodyを使うとUse Gravityのチェックボックスを入れるだけで簡単に重力が働くようになるが、実際にはUnityエディタの水面下でそうした処理が行われている。

CharacterController.isGroundedで接地判定

重力を発生させる仕組みはこうだ。

  • 1)3Dオブジェクトが接地しているか判定する
  • 2)接地していなければ下向きに移動させる
  • 3)接地していれば下向きに移動させるのをやめる/水平方向に移動できるようにする


なんか簡単そうっすね~
いや~ ホント簡単そうなので
キャラコンに最初から
この機能入れといてほしいよ~
Unity~


先に断っておくと、キャラクターコントローラーは初心者~中級者向きの「とりあえずオブジェクト動かすにはコレ付けとけばええ」というコンポーネントのようだ。プログラマ上級者はぜひ自分の力で組んでみることをおすすめする。

しかしこのインターハイブログは「とりあえず今、この夏の間だけまともなゲーム作りてぇ!Unityやりてぇ!」という初心者目線で書いているので、全力でキャラコン様を使わせてもらう。

そして前述したように、Rigidbody、コライダーはキャラコンと相性がわるいので使わない。そうなるとコライダーによるコリジョン(当たり)判定はどうすんねん!という話になるが、CharacterController.isGroundedという謎の呪文を使うことで地面への接地判定を行うことができるのだ。


コンポーネントには謎の呪文がいろいろあるものなんや。一覧はこちらのページ

この CharacterController.isGrounded で接地判定を行い、接地していなければ下向きの移動(重力)を発生させたスクリプトがこちらである。53-62行目に接地判定とその後の処理を書いてある。charaCon.isGrounded と表記しているのは、プロジェクト内の全てのキャラクターコントローラーに影響を出さないよう、7行目と24行目でキャラクターコントローラーの名前を定義しなおしているため。

まー細かいギモンは色々あると思うけど
とりあえずコレ使っとけば
Y軸マイナス方向に向かって落ちるよ



落ちるようになった剣太郎。接地しない時は重力=Y軸マイナス方向に向かう力が働いている。接地している時は重力は働いていない(しかし見た目には問題がない)

なんかよくわからないけど
すげぇーっす!
このスクリプトをただコピーしても
自分で作れるようにならないから
プログラミングを教えるのは
むずかしいなぁ……

ここだけ見れば複雑じゃないから
自分で改造して覚えていってくれぃ


ちなみにこのCharacterController.isGrounded、精度が甘いところもあるらしい。toRisouP先生という方が精度の改善方法をこちらのページで解説されている。

まっ 今はコレで動くようになったから
このへんにしといてやるぜ……

ハアハア…


このように、当たり前にある「重力」もプログラミングの世界では「Y軸マイナス方向に移動させる力」というふうに解釈することができる。このこじつけ力分析力は色々なプログラムを組む時の考え方の基本になるので大事にしていこう。

次回はジャンプの処理を入れてみることにする。果たして剣太郎はジャンプできるのか!?