プレイヤーの入力に対応する

前回のレッスンの 初めてのスクリプト作成 を踏まえて、どのゲームでも重要となるもうひとつの機能である、プレイヤーにコントロールを与えることについて見ていきましょう。これを追加するには、 sprite_2d.gd コードを修正する必要があります。

../../_images/scripting_first_script_moving_with_input.gif

Godotでは、プレイヤーの入力を処理するために、主に2つのツールが用意されています。

  1. 組み込みの入力コールバック。主に _unhandled_input()です。これは、_process()のように、プレーヤーがキーを押すたびに Godot が呼び出す組み込みの仮想関数です。例えば Space を押してジャンプするような、毎フレームで発生しないイベントに反応するために使用するツールです。入力コールバックについて詳しくは、 InputEvent (入力イベント) を参照してください。

  2. Inputシングルトン。シングルトンは、グローバルにアクセス可能なオブジェクトです。Godotはスクリプトでいくつかへのアクセスを提供しています。これは、毎フレーム入力があるかどうかを確認するのに適したツールです。

ここでは、Inputシングルトンを使用します。これは、プレイヤーがフレームごとに回転または移動したいかを知る必要があるからです。

回転させるために、新しい変数を使用する必要があります。これをdirectionとします。_process()関数の rotation += angular_speed * delta行を以下のコードに置き換えてください。

var direction = 0
if Input.is_action_pressed("ui_left"):
    direction = -1
if Input.is_action_pressed("ui_right"):
    direction = 1

rotation += angular_speed * direction * delta

ローカル変数directionは、プレイヤーが曲がりたい方向を表す乗数です。値が0なら、プレーヤーが左または右矢印キーを押していないことを意味します。値1なら、プレイヤーが右に曲がりたい、-1なら左に曲がりたいことを意味します。

To produce these values, we introduce conditional statements and the use of Input. A conditional statement starts with the if keyword in GDScript and ends with a colon. The condition is specifically the expression between the keyword and the colon at the end of the line.

このフレームでキーが押されたかどうかを確認するために、Input.is_action_pressed()を呼び出します。このメソッドは入力アクションを表す文字列を受け取り、アクションが押された場合はtrueを、それ以外の場合はfalseを返すようになっています。

上記で使用した2つのアクション、"ui_left" と "ui_right" は、すべてのGodotプロジェクトであらかじめ定義されています。それぞれ、プレイヤーがキーボードの左矢印と右矢印、またはゲームパッドの十字キーの左と右を押したときに起動します。

注釈

You can see and edit input actions in your project by going to Project > Project Settings and clicking on the Input Map tab.

最後に、directionをノードのrotationの更新時の乗数として使用します。rotation += angular_speed * direction * deltaとします。

次のように、 var Velocity = Vector2.UP.rotated(rotation) * Speedposition += Velocity * delta の行をコメントアウトします。

#var velocity = Vector2.UP.rotated(rotation) * speed

#position += velocity * delta

コメントアウトによって、前回の例題でユーザーの入力なしでアイコンを円運動させていたコードが実行されなくなります。

このコードでシーンを実行すると、 LeftRight を押したときにアイコンが回転します。

「上」ボタンを押すと動く

キーを押した時だけ動くようにするには、速度を計算するコードを修正する必要があります。コードのコメントを解除し、 var velocity で始まる行を以下のコードに置き換えます。

var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
    velocity = Vector2.UP.rotated(rotation) * speed

velocityVector2.ZEROという値で初期化します。これはVector型の組み込み定数の一つで、長さ0の2次元ベクトルを表します。

プレイヤーが"ui_up"アクションを押すと、velocityの値が更新され、スプライトが前に移動するようになります。

完全なスクリプト

参考までに、sprite_2d.gdファイル全体は次のようになります。

extends Sprite2D

var speed = 400
var angular_speed = PI


func _process(delta):
    var direction = 0
    if Input.is_action_pressed("ui_left"):
        direction = -1
    if Input.is_action_pressed("ui_right"):
        direction = 1

    rotation += angular_speed * direction * delta

    var velocity = Vector2.ZERO
    if Input.is_action_pressed("ui_up"):
        velocity = Vector2.UP.rotated(rotation) * speed

    position += velocity * delta

シーンを実行すると、左右の矢印キーで回転し、 Up を押して前進することができるはずです。

../../_images/scripting_first_script_moving_with_input.gif

要約

要約すると、Godotのすべてのスクリプトはクラスを表し、エンジンの組み込みクラスの 1 つを拡張します。クラスが継承するノードタイプにより、スプライトの場合は rotationposition などのプロパティにアクセスできるようになります。また、この例では使用できなかった多くの関数も継承します。

GDScript では、ファイルの先頭に置いた変数は、クラスのプロパティで、メンバー変数とも呼ばれます。また、変数以外にも関数を定義することができますが、これはほとんどの場合、クラスのメソッドになります。

Godotは、クラスとエンジンを接続するために定義可能ないくつかの仮想関数を提供します。例えば、_process()はフレームごとにノードに変更を適用し、_unhandled_input()はユーザからキーやボタンを押すなどの入力イベントを受け取ります。他にもたくさんの仮装関数があります。

The Input singleton allows you to react to the player's input anywhere in your code. In particular, you'll get to use it in the _process() loop.

次のレッスン シグナルの使用 では、スクリプトの中でノードにトリガーコードを持たせることで、スクリプトとノードの関係を構築します。