Godot4 CharacterBody2D のスケルトンコードの仕組み

無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 では、CharacterBody2D クラスを使うことで簡単に左右に移動したりジャンプする挙動を実装できます。

Godot4 Polygon2Dの地形で CharacterBody2D のキャラを動かした例

そのために自動的に作られるスケルトンコードがどのように、その動きを実現しているのか、スクリプトの処理について紹介します。

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※紹介するスクリプトは自己責任でお使いください。

関連記事

前回までの3話で、AnimatableBody2D ノードなどを使って指定した位置を往復する動く地形を作りました。

以前の記事では、 2D の左右移動やジャンプ移動ができる CharacterBody2D クラスを使って、操作するキャラクターを作成する手順を紹介しました。

CharacterBody2D のスケルトンコード

スケルトンコードは、シーンドックで CharacterBody2D ノード選択して、右上の+マークのついた「選択したノードに新規または既存のスクリプトをアタッチする。」ボタンを押したあと、「ノードにスクリプトをアタッチする」ダイアログでパスを確認して「作成」ボタンを押すと作られます。
※下図の GodotSan は CharacterBody2D ノードをリネームしたものです。

Godot4 CharacterBody2D で移動させるキャラのシーンを作成8

Script ワークスペースで、作成したスクリプトを左側のリストから選択すると以下のようなスケルトンコードが CharacterBody2D の場合は作られます。
このスクリプトだけで、落下、着地、左右移動、ジャンプが実装されています。

extends CharacterBody2D


const SPEED = 300.0
const JUMP_VELOCITY = -400.0

func _physics_process(delta):
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("ui_left", "ui_right")
	if direction:
		velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)

	move_and_slide()

定数の意味

CharacterBody2D のスケルトンコードでは、2つの定数が宣言され、処理で使われています。

GD スクリプトでは定数を const で定義します。
var による変数と異なり、値をあとで変更できません

定数

定数はゲームの実行中に変更することができない値のことです。これらの値はコンパイル時に確定している必要があります。 const キーワードを使うことで定数に名前を付けることができます。定数を宣言したよりも後に値を代入しようとすると、エラーが発生します。

値を変更するつもりがないのなら、定数を用いることを推奨します。

GDScriptリファレンス — Godot Engine (4.x)の日本語のドキュメント

スケルトンコードでは、左右へ移動する際の加速度 SPEED と、ジャンプ時に上方向(重力の反対方向)への加速度 JUMP_VELOCITY が定数として使われています。
これらをゲーム中に変化させたい場合は var で変数に置き換えると良いでしょう。

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

_physics_process 関数内の処理

以下は、物理演算フレーム処理を行う _physics_process イベント関数内の処理を3つに分けて処理される順番に紹介します。
引数の delta前回同イベント関数を呼び出した後の経過時間です。

物理処理は、同様の仮想関数 _physics_process() で動作します。これはゲーム世界に衝突判定を持つキャラクターの制御など、各物理ステップの前に実行する必要がある処理に使用します。前述のとおり、 _physics_process() は物理的な相互作用を安定させるために、可能な限り固定時間間隔(デフォルトでは毎秒60回)で呼び出されます。この間隔は、プロジェクト設定の Physics -> Common-> Physics Fps で変更できます。

アイドル処理と物理処理 — Godot Engine (4.x)の日本語のドキュメント

落下

is_on_floor 関数で、 false の場合、つまり着地していない空中にいる状態の場合に、重力のベクトルと同じ方向に、経過時間 (delta) 分の加速度を加えて、落下させます。
※ Input.get_gravity() ではなく PhysicsBody2D.get_gravity() です。
※ is_on_floor 関数で着地しているか判定できるのは素晴らしい!

	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

Returns the gravity vector computed from all sources that can affect the body, including all gravity overrides from Area2D nodes and the global world gravity.

Area2D ノードおよびグローバル ワールド重力からのすべての重力オーバーライドを含む、ボディに影響を与える可能性のあるすべてのソースから計算された重力ベクトルを返します。
PhysicsBody2D — Godot Engine (4.x)の日本語のドキュメント get-gravity

ジャンプ

ジャンプ( ui_accept アクション)の入力があった際に、着地していれば、定数で指定した加速度を上方向に設定して、キャラクターを上方向に加速させます。
ui_accept アクションはスペースキーなどに対応していて、最初からプロジェクト設定に割り当てられています。

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

左右移動と入力がない場合の減速

左右移動の入力があれば、その方向に SPEED 定数でキャラクターを加速させます。
入力がない場合は、move_toward 関数で SPEED を上限として横方向の加速度を 0 に近づけて、減速して止まるようにします。

例えば、move_toward の処理で、横方向の加速度が 10 で、SPEED が 2 の場合、1回の処理では上限の 2 だけ 0 に近づけるので、 8, 6, 4, 2, 0 と 5 回の physics_process で入力がない場合にキャラクターが止まり、それまでは少し滑ったような動きをします。

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("ui_left", "ui_right")
	if direction:
		velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)

Input.get_axis は指定した二つのアクション(左右など相反する入力)を比較して、左右どちらの入力が大きいかを +, – の値で教えてくれます。
0 の場合は、指定したアクションの入力がないことを表し、続きの if 文では else の処理がそれにあたります。

Get axis input by specifying two actions, one negative and one positive.

This is a shorthand for writing Input.get_action_strength("positive_action") - Input.get_action_strength("negative_action").

2 つのアクション (負のアクションと正のアクション) を指定して軸入力を取得します。
Input — Godot Engine (4.x)の日本語のドキュメント

move_toward(a, b, c) は a の値を c を上限にして b に近づけた値を返します。
※以下の引用は Vector2 版です。

Returns a new vector moved toward to by the fixed delta amount. Will not go past the final value.

固定デルタ量だけ に向かって移動した新しいベクトルを返します。最終値を超えることはありません。

Vector2 — Godot Engine (4.x)の日本語のドキュメント

設定した加速度で移動させて衝突の相互作用を行う

今まで設定してきたキャラクターの加速度 velocity メンバ変数をもとに、実際に移動させて衝突などを行います。
RigidBody2D と異なり、衝突した後の相互作用は行わず単純に壁にぶつかったらとまるなど、衝突の後の処理は簡素化されているので、2D ゲームの挙動に近い動きを実現してくれます。

move_and_slide

move_and_slide() メソッドは、一方のボディをもう一方のボディに沿ってスライドさせたいという一般的なケースで衝突応答を単純化することを目的としています。 たとえば、プラットフォーマーやトップダウンゲームで特に役立ちます。

Using CharacterBody2D/3D — Godot Engine (4.x)の日本語のドキュメント

まとめ

今回は、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 では、簡単に左右に移動したりジャンプする挙動を実装できる CharacterBody2D クラスのスケルトンコードがどのように、その動きを実現しているのか、スクリプトの処理について紹介しました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました