この記事について

Godotでキーを押しても反応しないときは、Input Mapへの登録と、スクリプトで使っているアクション名を分けて確認すると原因を絞れます。

この記事では、左右の矢印キーでアイコンを動かし、Spaceを1回押すたびに回数を増やすサンプルを作ります。「押している間」と「押した瞬間」の違いを、同じ画面で確かめます。Godot 4.6.3のGDScriptを使い、エディターの項目名は英語表記で説明します。

この記事でわかること

  • Input Mapへアクションとキーを登録する方法
  • 押し続ける操作と、1回だけ実行する操作の使い分け
  • 入力が反応しないときに確認する場所

基本手順

手順1:確認用のシーンを作る

空のプロジェクトでScene → New Sceneを開き、2D Sceneを選びます。ルートのNode2DをInputDemoに名前変更し、input_demo.tscnとして保存します。

InputDemoの子としてSprite2DとLabelを追加し、Sprite2DをPlayer、LabelをStatusに名前変更します。以下の3ノードだけを使います。

InputDemo (Node2D)
├ Player (Sprite2D)
└ Status (Label)

FileSystemのicon.svgを、PlayerのInspectorにあるTextureへドラッグします。PlayerのTransform → PositionをX=320、Y=240にします。StatusのLayout → Transform → PositionはX=32、Y=32、Textは「Space: 0回」にします。文字が小さい場合はTheme Overrides → Font Sizes → Font Sizeを24にします。

このサンプルは入力の確認用です。アイコンは壁と衝突せず、ウィンドウの外へも移動します。

InputDemo、Player、StatusのツリーとPlayerのTextureおよび初期位置
手順1:Playerにicon.svgを設定し、PositionをX=320、Y=240にします。

手順2:Input Mapへ3つのアクションを追加する

Project → Project Settingsを開き、Input Mapタブへ切り替えます。Add New Actionの欄にmove_leftと入力し、Addを押します。同じ操作でmove_rightとcount_pressも追加します。

Input MapタブのAdd New Action入力欄とAddボタン
手順2:Input MapのAdd New Actionへ名前を入力し、Addで追加します。

アクション名は、操作を表す自分で決める名前です。ここではコードと一致させるため、次の綴りで登録します。

  • move_left:左へ動かす
  • move_right:右へ動かす
  • count_press:回数を1増やす

手順3:各アクションへキーを割り当てる

move_leftの右側にある+を押し、入力を受け付ける欄で左矢印キーを押します。Additional Optionsのキー種別はKeycode (Latin Equivalent)を選び、上部にLeftと表示されることを確認してOKを押します。同様にmove_rightへ右矢印をKeycode (Latin Equivalent)で登録します。count_pressへはSpaceを登録し、こちらのキー種別はPhysical Keyにします。

アクションの行を開き、それぞれの下にキーが表示されていることを確認します。アクション名を追加しただけでは、まだキーは割り当てられていません。確認できたらCloseで設定を閉じます。

Left、Right、Space Physicalが3つのアクションに割り当てられたInput Map
手順3:move_leftはLeft、move_rightはRight、count_pressはSpace (Physical)の表示を確認します。

今回の例では矢印とSpaceを使います。文字キーを追加するときは、文字としてのキーを使うのか、キーボード上の物理的な位置を使うのかで設定の意味が変わります。まずはこの3キーで動作を確認してから増やしてください。

手順4:押し続ける操作と単発の操作を書く

InputDemoを選び、Attach Scriptからres://input_demo.gdを作ります。GDScriptを選び、テンプレートを使わずに作成したら、次の内容にします。

extends Node2D

const SPEED: float = 240.0
var press_count: int = 0

@onready var player: Sprite2D = $Player
@onready var status: Label = $Status

func _process(delta: float) -> void:
    var direction := Input.get_axis("move_left", "move_right")
    player.position.x += direction * SPEED * delta

    if Input.is_action_just_pressed("count_press"):
        press_count += 1
        status.text = "Space: %d回" % press_count
input_demo.gdの全コード。左右移動とSpaceの単発入力処理を赤枠で表示
手順4:get_axis()の値にSPEEDとdeltaを掛けて移動し、Spaceはis_action_just_pressed()で1回ずつ数えます。

Input.get_axis()は、左のアクションを負、右を正として入力をまとめます。今回のキー割り当てなら、左だけで-1、右だけで1、どちらも押していないと0です。両方を押した場合も差が0になるため停止します。

SPEEDは1秒あたりに動く距離です。毎フレームの移動量にdeltaを掛け、フレームの長さを反映します。これは入力を見やすくする単純な座標移動で、CharacterBody2Dの衝突付き移動とは実装が異なります。

is_action_just_pressed()は、押し始めたフレームまたは物理更新のタイミングでtrueになります。この例では_process()内で調べるため、Spaceを押し続けても毎フレーム加算されません。is_action_pressed()へ変えると押している間ずっとtrueになるので、単発の加算には使わないようにします。

手順5:実行画面で入力を確かめる

シーンとスクリプトを保存し、Run Current Sceneから実行します。Windows・Linuxの標準ショートカットはF6です。実行した画面をクリックして、キーボード入力を受け取る状態にします。

  1. 左矢印を短く押し、アイコンが左へ動くことを確認します
  2. 右矢印を短く押し、右へ動くことを確認します
  3. Spaceを押したままにして、表示が1回だけ増えることを確認します
  4. Spaceを離してからもう一度押し、さらに1回増えることを確認します

確認中にアイコンが画面外へ出た場合は、一度停止して実行し直します。初期位置から再開できます。

初期位置にあるアイコンと右矢印で右へ移動したアイコンの比較
手順5:右矢印を押すと、初期位置から右へ移動します。
Space長押し中は1回、離して再度押すと2回になる実行画面の比較
手順5:Spaceを押し続けても1回のままです。離してからもう一度押すと2回になります。

手順6:同じ操作へ別のキーを追加する

実行を止めてInput Mapへ戻り、move_leftへA、move_rightへDを追加してみます。既存の矢印キーは消さず、同じアクションへ追加します。物理位置で操作をそろえたい場合は、キー登録画面でPhysical Keyを選びます。

コードはmove_leftとmove_rightを見ているため、スクリプトを書き換えずに追加したキーも使えます。再実行し、矢印キーと追加したキーの両方で動くか確かめてください。

move_leftにLeftとA Physical、move_rightにRightとD Physicalを登録したInput Map
手順6:矢印キーを残したまま、同じアクションへA (Physical)とD (Physical)を追加します。

うまくいかないときの確認箇所

アクションが存在しないというエラーが出る

Input Mapの名前と、コード内の引用符で囲まれた名前を比較します。move_leftとMove_Leftは別の名前です。末尾へ空白が入っていないかも確認します。

エラーはないのに動かない

まず実行画面をクリックし、エディターのコード欄などに入力フォーカスが残っていないか確認します。次にInput Mapのアクションを開き、キーが実際に登録されているか見ます。最後にInputDemoへスクリプトが付いているかを確認してください。

Spaceを押すと数値が一気に増える

単発の加算にis_action_pressed()を使っていないか確認します。押し続ける間の状態を見る関数なので、毎フレームpress_countへ加算すると大きな数になります。この記事のコードではis_action_just_pressed()を使います。

メニューを開いてもキャラクターが動く

Inputのポーリングは入力全体の状態を読みます。UIがイベントを受け取っただけでは、Input.get_axis()が自動的に0になるわけではありません。メニュー中に移動を止めたい場合は、移動処理を有効にする条件や、一時停止処理を別に設けます。

イベント処理の中でも同じ書き方でよい?

_input(event)や_unhandled_input(event)で「今届いたイベント」を判定する場合は、event.is_action_pressed(“count_press”)を使います。今回の毎フレーム調べる方法とイベントを受け取る方法を同時に書くと、同じ操作を二重に処理する原因になるため、まずはどちらか一方で確認してください。

まとめ

Input Mapでは、アクションを作る操作と、そのアクションへキーを割り当てる操作の両方が必要です。スクリプトではキーの名前ではなく、登録したアクション名を使います。

移動のような押し続ける処理と、回数を増やすような1回だけの処理を分けると、入力の実装を整理できます。反応しないときは、入力フォーカス、キー割り当て、アクション名、スクリプトの順に見直してみてください。