Godot 4 で「「KeyboardMover (キーボード移動)」 の実装記事とチュートリアルです。
このコンポーネントを使えば、プレイヤーのスクリプトに移動コードを一切書かずに、キャラクターをWASDや矢印キーで動かせるようになります。
通常のGodot開発では CharacterBody2D に直接移動コードを書きますが、今回は「移動機能を独立した部品(ノード)」として作成します。これにより、プレイヤーだけでなく、デバッグ用のカメラやNPCなど、あらゆる物体に「移動能力」を後付けできるようになります。
目次
1. コンポーネントのコード (Full Code)
まず、以下のコードをコピーして、KeyboardMover.gd という名前で保存してください。
class_name KeyboardMover
extends Node
## 親ノード(CharacterBody2D)をキーボード入力で移動させるコンポーネント
## 矢印キー または WASDキーに対応しています。
# --- 設定パラメータ ---
@export_group("Movement Settings")
@export var speed: float = 200.0 ## 最大移動速度
@export var acceleration: float = 800.0 ## 加速度(動き出しの滑らかさ)
@export var friction: float = 1000.0 ## 摩擦(停止時の滑らかさ)
@export_group("Input Map")
@export var action_left: String = "ui_left"
@export var action_right: String = "ui_right"
@export var action_up: String = "ui_up"
@export var action_down: String = "ui_down"
# --- 内部変数 ---
var _parent: CharacterBody2D
func _ready() -> void:
# 親ノードを取得し、型チェックを行う
_parent = get_parent() as CharacterBody2D
if not _parent:
push_error("KeyboardMover: 親ノードが CharacterBody2D ではありません。このコンポーネントは動作しません。")
set_physics_process(false) # 処理を停止
func _physics_process(delta: float) -> void:
# 入力ベクトルを取得 (正規化も自動で行われます)
var input_dir: Vector2 = Input.get_vector(
action_left,
action_right,
action_up,
action_down
)
if input_dir != Vector2.ZERO:
# 入力がある場合:加速しながら最大速度へ向かう
_parent.velocity = _parent.velocity.move_toward(input_dir * speed, acceleration * delta)
else:
# 入力がない場合:摩擦で減速して停止する
_parent.velocity = _parent.velocity.move_toward(Vector2.ZERO, friction * delta)
# 親ノードを物理移動させる
_parent.move_and_slide()
2. 使い方チュートリアル
このコンポーネントを使って、実際にキャラクターを動かす手順です。
手順①:プレイヤー(親)を用意する
- 新しいシーンを作成し、ルートノードを
CharacterBody2Dにします(名前はPlayerなど)。 - 当たり判定 (
CollisionShape2D) と画像 (Sprite2D) を子ノードに追加し、適当に設定します。- ※ここまでは通常のキャラクター作成と同じです。
手順②:コンポーネントをアタッチする
ここがポイントです。プレイヤー自身にスクリプトを書く代わりに、先ほどのコンポーネントをくっつけます。
Playerノードを選択し、右クリック > 「子ノードを追加 (Add Child Node)」。- ただの
Nodeを追加し、名前をKeyboardMoverに変更します。 - この
KeyboardMoverノードに、先ほど作成したスクリプトKeyboardMover.gdをドラッグ&ドロップ(またはアタッチ)します。
シーン構成図:
Plaintext
Player (CharacterBody2D)
├── Sprite2D (画像)
├── CollisionShape2D (当たり判定)
└── KeyboardMover (Node) <--- ここにスクリプトが付いている
手順③:パラメータを調整する
インスペクターを見てください。スクリプト変数が表示されています。
- Speed: 移動速度(例:
300に上げると速くなります) - Acceleration: 数値を小さくすると、氷の上のようにツルツル滑りながら加速します。
- Friction: 数値を小さくすると、キーを離してもすぐには止まらず、慣性で滑ります。
手順④:実行する
シーンを再生(F6キー)してください。
矢印キー(またはWASD)でキャラクターが滑らかに移動すれば成功です!
3. このコンポーネントのメリット・応用
この方式で作ると、以下のような「嬉しいこと」があります。
- プレイヤーのスクリプトが汚れない
- プレイヤー本体のスクリプト(もし作るとしても)には、HP管理やアニメーション制御などのコードだけを書けばよく、移動ロジックと混ざりません。
- 動きの質感を使い回せる
- 「氷のステージ」では
Frictionを下げた別の設定にする、などをインスペクター上の数値変更だけで管理できます。
- 「氷のステージ」では
- 一時的に動けなくするのが簡単
- イベント中などでプレイヤーを動けなくしたい場合、このノードの
process_modeをDisabledにするだけで、移動機能だけを完全にオフにできます。
- イベント中などでプレイヤーを動けなくしたい場合、このノードの
# 例:イベント会話中に移動を禁止するコード
$KeyboardMover.process_mode = Node.PROCESS_MODE_DISABLED
補足:トップダウン型以外のゲームの場合
このコードは「8方向移動(RPGや見下ろし型アクション)」向けです。
横スクロールアクション(サイドビュー)で使う場合は、Y軸の入力を無視するか、重力コンポーネント(リストのNo.3)と組み合わせて使用することになります。
