概要
Godotの入力処理には、ボタンの状態に応じて複数のメソッドが用意されています。適切なメソッドを選ぶことで、自然で反応の良い操作感を実現できます。
最初はis_action_pressed()だけを使っていたため、「ジャンプボタンを押している間、キャラクターが上に飛び続ける」というバグを作ってしまいました。is_action_just_pressed()を知って「そうか、押した瞬間だけ判定すればいいのか!」と理解した時のことは今でも覚えています。
入力状態の種類
is_action_just_pressed()
- 判定: ボタンが押された瞬間のみtrue
- 用途: ジャンプ、攻撃、メニュー開閉など1回限りのアクション
is_action_pressed()
- 判定: ボタンが押されている間ずっとtrue
- 用途: 移動、ダッシュ、チャージなど継続的なアクション
is_action_just_released()
- 判定: ボタンが離された瞬間のみtrue
- 用途: チャージ攻撃の発動、長押し判定の終了
実用的な使い分け例
func _process(delta):
# 1回限りのアクション
if Input.is_action_just_pressed("jump"):
if is_on_floor():
velocity.y = JUMP_VELOCITY
if Input.is_action_just_pressed("attack"):
perform_attack()
if Input.is_action_just_pressed("pause"):
toggle_pause_menu()
# 継続的なアクション
if Input.is_action_pressed("dash"):
current_speed = dash_speed
else:
current_speed = normal_speed
# チャージ系の処理
if Input.is_action_pressed("charge"):
charge_power += charge_rate * delta
charge_power = min(charge_power, max_charge)
# ボタンを離した瞬間の処理
if Input.is_action_just_released("charge"):
fire_charged_shot(charge_power)
charge_power = 0.0
よくある間違いと対策
間違い:連続発動してしまう
# 悪い例:毎フレーム弾が発射される
func _process(delta):
if Input.is_action_pressed("shoot"): # 間違い!
fire_bullet() # 毎フレーム実行される
# 良い例:ボタンを押した瞬間のみ発射
func _process(delta):
if Input.is_action_just_pressed("shoot"): # 正しい
fire_bullet() # 1回だけ実行
間違い:移動が瞬間的になる
# 悪い例:カクカクした移動
func _physics_process(delta):
if Input.is_action_just_pressed("move_right"): # 間違い!
position.x += 10 # 瞬間移動
# 良い例:滑らかな移動
func _physics_process(delta):
if Input.is_action_pressed("move_right"): # 正しい
velocity.x = speed
else:
velocity.x = 0
高度な使い方:アナログ入力
get_action_strength()
ゲームパッドのアナログスティックやトリガーの入力強度(0.0〜1.0)を取得
func _process(delta):
# アナログ入力の取得
var move_strength = Input.get_action_strength("move_forward")
var brake_strength = Input.get_action_strength("brake")
# 車の加速処理
if move_strength > 0.0:
velocity += forward_direction * acceleration * move_strength * delta
# ブレーキ処理
if brake_strength > 0.0:
velocity = velocity.move_toward(Vector2.ZERO, brake_force * brake_strength * delta)
使い分け早見表
用途 | 使用する関数 | 具体例 |
---|---|---|
1回限りのアクション | is_action_just_pressed() | ジャンプ、攻撃、メニュー開閉、アイテム使用 |
継続的なアクション | is_action_pressed() | 移動、ダッシュ、チャージ、エイム |
離した瞬間の処理 | is_action_just_released() | チャージ攻撃発動、長押し判定の終了 |
アナログ入力 | get_action_strength() | 車のアクセル、武器のエイム精度 |
実装例:チャージ攻撃システム
extends Node2D
@export var charge_rate = 2.0
@export var max_charge = 3.0
var charge_power = 0.0
func _process(delta):
# チャージ中の処理
if Input.is_action_pressed("charge_attack"):
charge_power += charge_rate * delta
charge_power = min(charge_power, max_charge)
update_charge_indicator()
# チャージ解放
if Input.is_action_just_released("charge_attack"):
if charge_power >= 1.0: # 最低チャージ量
fire_charged_shot(charge_power)
charge_power = 0.0
hide_charge_indicator()
デバッグのコツ
func _process(delta):
# 入力状態を可視化
if Input.is_action_just_pressed("debug"):
print("Debug key pressed!")
if Input.is_action_pressed("debug"):
$DebugLabel.text = "Holding..."
if Input.is_action_just_released("debug"):
print("Debug key released!")
$DebugLabel.text = ""
実装して学んだこと
これらの入力メソッドの使い分けは、ゲームの操作感に直結する重要な要素です。特にjust_releasedを使ったチャージ攻撃の実装は、プレイヤーがタイミングをコントロールできる感覚があって、とても気持ち良いです。
また、get_action_strength()を使ったアナログ入力は、車のゲームでの加速感をリアルに再現できて感動しました。キーボードでは0か1の入力しかできませんが、コントローラーでは「ちょっとだけ加速」のような細かい制御ができるので、ゲームの深みが増します。