Godot Engine の公式チュートリアル Using KinematicBody2D の自分用まとめ。
現在の Godot Engine のバージョンは 3.1.2
2Dの物理エンジンに関わるノードはPhysicsBody2Dであり、3つの下位ノードを用途によって使い分ける。
- KinematicBody2D
物理エンジンによって自動で動かされず、スクリプトによって明示的に動かす必要がある。衝突などの干渉はする。 - RigidBody2D
- 物理エンジンによって自動で動き、重力や質量、摩擦係数などのパラメータを入力することができる。
- StaticBody2D
- 床や壁などの動かないものに使う。動く足場などのためにスクリプトで動かすこともできるが、KinematicBody2Dと違い、それが他のオブジェクトと接触したときにどう動くか、などといった細かいことを指定することはできない。
KinematicBody2D を動かすときのメソッド
基本的には _physics_process() 内で使う。
move_and_collide()
引数は移動させる分のベクトル。_physics_process() のtimestepでの移動分なので、移動量としてオブジェクトの速度に _physics_process()の引数deltaをかけたベクトルを入れる。
なにかと衝突する場合、衝突地点まで移動し、KinematicCollision2D のオブジェクトを返す。
KinematicCollision2D からその衝突に関する情報を引き出すことができる。
move_and_slide()
キャラを動かすための簡易版メソッド。deltaをかけずに速度を入力する。
なにかと衝突した場合そこで止まらずに衝突面に沿ってスライドする。
カスタマイズ用パラーメタをセットすることができる。
- floor_normal (デフォルト値 Vector2(0,0)) : 床の向きを指定する。is_on_floor(), is_on_wall(), is_on_ceiling() で床、壁、天井への接触を判定できるようになる。指定しないと全て壁への接触と見なされる。
- slope_stop_min_velocity (デフォルト値 5) : 坂に立ってるときに速さがこの値以下だと滑り落ちない。
- max_bounces (デフォルト値 4) : 一回の移動での衝突回数の上限。
- floor_max_angle (デフォルト値 0.785398 radians = 45° ) : 床と判断される最大の傾斜角度。
move_and_slide_with_snap()
move_and_slide メソッドに Vector2 のパラメータ snap を追加する。スナップベクトルが地面と接触する限り地面に吸い付いたままになる。
get_slide_collision()
move_and_slide メソッドが最後に呼び出されたときからの衝突のデータオブジェクトを返す。複数回衝突しうるので、引数として衝突のインデックスを渡す。衝突回数は get_slide_count() で得られる。
for i in range(get_slide_count()):
var coll = get_slide_collision(i)
#衝突に関する処理
move_and_collide() だと戻り値として衝突のデータが得られるが、move_and_slide() は複数回衝突する可能性があるためこういう仕様になってると思われる。
使い方に関するコメント
move_and_slide()の意味
move_and_collide() は、衝突が発生した場所で動きを止めてしまうので、キャラクターをオブジェクトに押し付けながら移動させようとするとそこで引っかかって動かなくなってしまう。
move_and_slide()を使うと引っかからずスムーズに動く。
一応 move_and_collide() のみで同様の挙動を実装することはできる。
キャラの速度ベクトルの更新
大体の場合キャラの速度に当たるベクトルをローカル変数として保持し、それを move_and_slide に引数として渡すことになるが、このメソッドは戻り値として移動した結果の速度を返す。
例えば壁面に斜めに当たったキャラが壁面に沿ってスライドしたとすると、壁面に沿った速度ベクトルが返される。
velocity=move_and_slide(velocity)
とするのは重要で、例えば2Dアクションで上から下にかかる重力をスクリプトで実装しているとき、velocity を更新しないと地面に立っている間も下方向への速度ベクトルが増え続けることになる。
move_and_slide_with_snap()の意味
これは例えばキャラが少し傾いた山なりの坂を横に移動したときの挙動に関係する。
物理エンジンの正確な挙動に従えば、山の頂点を通り過ぎる時にキャラが一瞬浮くことになるが、このメソッドを使うと常に地面を接触したまま山を通り過ぎることができる。
キャラをジャンプさせるときにはスナップしないようにしないとダメ。