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. 使い方チュートリアル

このコンポーネントを使って、実際にキャラクターを動かす手順です。

手順①:プレイヤー(親)を用意する

  1. 新しいシーンを作成し、ルートノードを CharacterBody2D にします(名前は Player など)。
  2. 当たり判定 (CollisionShape2D) と画像 (Sprite2D) を子ノードに追加し、適当に設定します。
    • ※ここまでは通常のキャラクター作成と同じです。

手順②:コンポーネントをアタッチする

ここがポイントです。プレイヤー自身にスクリプトを書く代わりに、先ほどのコンポーネントをくっつけます。

  1. Player ノードを選択し、右クリック > 「子ノードを追加 (Add Child Node)」
  2. ただの Node を追加し、名前を KeyboardMover に変更します。
  3. この KeyboardMover ノードに、先ほど作成したスクリプト KeyboardMover.gd をドラッグ&ドロップ(またはアタッチ)します。

シーン構成図:

Plaintext

Player (CharacterBody2D)
 ├── Sprite2D (画像)
 ├── CollisionShape2D (当たり判定)
 └── KeyboardMover (Node) <--- ここにスクリプトが付いている

手順③:パラメータを調整する

インスペクターを見てください。スクリプト変数が表示されています。

  • Speed: 移動速度(例: 300 に上げると速くなります)
  • Acceleration: 数値を小さくすると、氷の上のようにツルツル滑りながら加速します。
  • Friction: 数値を小さくすると、キーを離してもすぐには止まらず、慣性で滑ります。

手順④:実行する

シーンを再生(F6キー)してください。

矢印キー(またはWASD)でキャラクターが滑らかに移動すれば成功です!


3. このコンポーネントのメリット・応用

この方式で作ると、以下のような「嬉しいこと」があります。

  • プレイヤーのスクリプトが汚れない
    • プレイヤー本体のスクリプト(もし作るとしても)には、HP管理やアニメーション制御などのコードだけを書けばよく、移動ロジックと混ざりません。
  • 動きの質感を使い回せる
    • 「氷のステージ」では Friction を下げた別の設定にする、などをインスペクター上の数値変更だけで管理できます。
  • 一時的に動けなくするのが簡単
    • イベント中などでプレイヤーを動けなくしたい場合、このノードの process_modeDisabled にするだけで、移動機能だけを完全にオフにできます。
# 例:イベント会話中に移動を禁止するコード
$KeyboardMover.process_mode = Node.PROCESS_MODE_DISABLED

補足:トップダウン型以外のゲームの場合

このコードは「8方向移動(RPGや見下ろし型アクション)」向けです。

横スクロールアクション(サイドビュー)で使う場合は、Y軸の入力を無視するか、重力コンポーネント(リストのNo.3)と組み合わせて使用することになります。