入力の例

はじめに

このチュートリアルでは、GodotのInputEvent システムを使用してプレイヤーの入力をキャプチャする方法を学習します。ゲームで使用できる入力には、キーボード、ゲームパッド、マウスなど、さまざまな種類があり、それらの入力をゲームのアクションに変換するさまざまな方法があります。このドキュメントでは、最も一般的なシナリオをいくつか紹介します。これらのシナリオは、独自のプロジェクトの出発点として使用できます。

注釈

Godotの入力イベントシステムの動作の詳細については、InputEvent(入力イベント) を参照してください。

イベント対ポーリング

特定の入力イベントにゲームを応答させたい場合があります - たとえば、「ジャンプ」ボタンを押します。他の状況では、移動など、キーが押されている限り何かを実行したい場合があります。最初のケースでは、入力イベントが発生するたびに呼び出される _input() 関数を使用できます。 2番目の場合、Godotは Input シングルトンを提供します。これを使用して、入力の状態を照会できます。

例:

func _input(event):
    if event.is_action_pressed("jump"):
        jump()


func _physics_process(delta):
    if Input.is_action_pressed("move_right"):
        # Move as long as the key/button is pressed.
        position.x += speed * delta
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent.IsActionPressed("jump"))
    {
        Jump();
    }
}

public override void _PhysicsProcess(float delta)
{
    if (Input.IsActionPressed("move_right"))
    {
        // Move as long as the key/button is pressed.
        position.x += speed * delta;
    }
}

これにより、実行する入力処理のタイプを自由に組み合わせることができます。

このチュートリアルの残りの部分では、_ input() で個々のイベントをキャプチャすることに焦点を当てます。

入力イベント

入力イベントは、InputEvent を継承するオブジェクトです。イベントタイプに応じて、オブジェクトにはそのイベントに関連する特定のプロパティが含まれます。イベントが実際にどのように見えるかを確認するには、ノードを追加し、次のスクリプトをアタッチします:

extends Node


func _input(event):
    print(event.as_text())
using Godot;
using System;

public class Node : Godot.Node
{
    public override void _Input(InputEvent inputEvent)
    {
        GD.Print(inputEvent.AsText());
    }
}

キーを押したり、マウスを動かしたり、他の入力を実行したりすると、出力ウィンドウで各イベントがスクロールして表示されます。出力の例を次に示します:

A
InputEventMouseMotion : button_mask=0, position=(108, 108), relative=(26, 1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(108, 107), button_mask=1, doubleclick=false
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=false
S
F
Alt
InputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)

ご覧のとおり、結果は入力の種類によって大きく異なります。キーイベントはキーシンボルとしても印刷されます。たとえば、InputEventMouseButton を考えてみましょう。次のクラスから継承します:

  • InputEvent - すべての入力イベントの基本クラス
  • InputEventWithModifiers - ShiftAlt などのモディファイヤが押されているかどうかをチェックする機能を追加します。
  • InputEventMouseposition などのマウスイベントプロパティを追加します
  • InputEventMouseButton - 押されたボタンのインデックス、ダブルクリックかどうかなどが含まれます。

ちなみに

イベントの操作中は、イベントの種類で使用可能なプロパティとメソッドを確認できるように、クラス参照を開いたままにすることをお勧めします。

InputEventKeyposition を呼び出すなど、その型を含まない入力型のプロパティにアクセスしようとすると、エラーが発生する可能性があります。これを回避するには、まずイベントタイプをテストしてください:

func _input(event):
    if event is InputEventMouseButton:
        print("mouse button event at ", event.position)
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent is InputEventMouseButton mouseEvent)
    {
        GD.Print($"mouse button event at {mouseEvent.Position}");
    }
}

入力マップ

InputMap は、さまざまな入力を処理する最も柔軟な方法です。これを使用するには、名前付き入力 アクション を作成します。これに、キー入力やマウスクリックなど、任意の数の入力イベントを割り当てることができます。新しいGodotプロジェクトには、すでに定義されている多数のデフォルトアクションが含まれています。それらを表示し、独自に追加するには、[プロジェクト] -> [プロジェクト設定]を開き、インプットマップタブを選択します。

../../_images/inputs_inputmap.png

アクションのキャプチャ

アクションを定義したら、探しているアクションの名前を渡すことで is_action_pressed()is_action_released() を使用してスクリプトでアクションを処理できます:

func _input(event):
    if event.is_action_pressed("my_action"):
        print("my_action occurred!")
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent.IsActionPressed("my_action"))
    {
        GD.Print("my_action occurred!");
    }
}

キーボードイベント

キーボードイベントは InputEventKey でキャプチャされます。代わりに入力アクションを使用することをお勧めしますが、重要なイベントを具体的に調べたい場合もあります。この例では、T を確認します:

func _input(event):
    if event is InputEventKey and event.pressed:
        if event.scancode == KEY_T:
            print("T was pressed")
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed)
    {
        if ((KeyList)keyEvent.Scancode == KeyList.T)
        {
            GD.Print("T was pressed");
        }
    }
}

ちなみに

スキャンコード定数のリストについては、@GlobalScope_KeyList を参照してください。

キーボード・モディファイヤ

モディファイヤのプロパティは、InputEventWithModifiers から継承されます。これにより、ブールプロパティを使用してモディファイヤの組み合わせを確認できます。 T が押されたときに起こることが1つあり、Shift + T のときは何か違うことが起こると想像してみましょう。

func _input(event):
    if event is InputEventKey and event.pressed:
        if event.scancode == KEY_T:
            if event.shift:
                print("Shift+T was pressed")
            else:
                print("T was pressed")
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed)
    {
        switch ((KeyList)keyEvent.Scancode)
        {
            case KeyList.T:
                GD.Print(keyEvent.Shift ? "Shift+T was pressed" : "T was pressed");
                break;
        }
    }
}

ちなみに

スキャンコード定数のリストについては、@GlobalScope_KeyList を参照してください。

マウスイベント

マウスイベントは InputEventMouse クラスから派生し、2つのタイプに分けられます: InputEventMouseButton および InputEventMouseMotion です。これは、すべてのマウスイベントに position プロパティが含まれることを意味することに注意してください。

マウスボタン

マウスボタンのキャプチャは、キーイベントの処理に非常に似ています。@GlobalScope_ButtonList には、考えられる各ボタンの BUTTON_* 定数のリストが含まれており、イベントの button_index プロパティで報告されます。スクロールホイールもボタンとしてカウントされることに注意してください - 。スクロールホイールは、正確には2つのボタンにわかれていて、BUTTON_WHEEL_UPBUTTON_WHEEL_DOWN の両方が別々のイベントであることに注意してください。

func _input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            print("Left button was clicked at ", event.position)
        if event.button_index == BUTTON_WHEEL_UP and event.pressed:
            print("Wheel up")
public override void _Input(InputEvent inputEvent)
{
    if (inputEvent as InputEventMouseButton mouseEvent && mouseEvent.Pressed)
    {
        switch ((ButtonList)mouseEvent.ButtonIndex)
        {
            case ButtonList.Left:
                GD.Print($"Left button was clicked at {mouseEvent.Position}");
                break;
            case ButtonList.WheelUp:
                GD.Print("Wheel up");
                break;
        }
    }
}

マウスモーション

InputEventMouseMotion イベントは、マウスが移動するたびに発生します。relative プロパティで移動の距離を確認できます。

マウスイベントを使用して Sprite ノードをドラッグアンドドロップする例を次に示します:

extends Node


var dragging = false
var click_radius = 32 # Size of the sprite.


func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
        if (event.position - $Sprite.position).length() < click_radius:
            # Start dragging if the click is on the sprite.
            if not dragging and event.pressed:
                dragging = true
        # Stop dragging if the button is released.
        if dragging and not event.pressed:
            dragging = false

    if event is InputEventMouseMotion and dragging:
        # While dragging, move the sprite with the mouse.
        $Sprite.position = event.position
using Godot;
using System;

public class Node2D : Godot.Node2D
{
    private bool dragging = false;
    private int clickRadius = 32; // Size of the sprite.

    public override void _Input(InputEvent inputEvent)
    {
        Sprite sprite = GetNodeOrNull<Sprite>("Sprite");
        if (sprite == null)
        {
            return; // No suitable node was found.
        }

        if (inputEvent is InputEventMouseButton mouseEvent && (ButtonList)mouseEvent.ButtonIndex == ButtonList.Left)
        {
            if ((mouseEvent.Position - sprite.Position).Length() < clickRadius)
            {
                // Start dragging if the click is on the sprite.
                if (!dragging && mouseEvent.Pressed)
                {
                    dragging = true;
                }
            }
            // Stop dragging if the button is released.
            if (dragging && !mouseEvent.Pressed)
            {
                dragging = false;
            }
        }
        else
        {
            if (inputEvent is InputEventMouseMotion motionEvent && dragging)
            {
                // While dragging, move the sprite with the mouse.
                sprite.Position = motionEvent.Position;
            }
        }
    }
}

タッチイベント

タッチスクリーンデバイスを使用している場合、タッチイベントを生成できます。InputEventScreenTouch はマウスクリックイベントに相当し、InputEventScreenDrag はマウスの動きとほぼ同じように機能します。

ちなみに

非タッチスクリーンデバイスでタッチイベントをテストするには、プロジェクト設定を開き、"Input Devices/Pointing" セクションに進みます。 "Emulate Touch From Mouse" を有効にすると、プロジェクトはマウスクリックとモーションをタッチイベントとして解釈します。