プレイヤーのスクリプトを書こう
スクリプトの作成
続いて「Player」ノードにスクリプトをアタッチします。
「Player」ノードを右クリックして「スクリプトをアタッチ」を選択します。「ノードにスクリプトをアタッチする」ダイアログが表示されますので「テンプレート」にチェックを入れて、そのまま「作成」ボタンを押します。
res://scn/player/player.gd
と保存されたはずです。
このplayer.gd
をScriptビューで開き、次のようにスクリプトを書き換えます。
extends CharacterBody2D const SPEED = 150.0 var is_act = true # クリア後の停止用フラグ @onready var size = get_viewport_rect().size func _ready() -> void: $AnimatedSprite2D.play() func _physics_process(_delta: float) -> void: # クリア後の停止処理 if ! is_act: return # キー入力から方向を得る var x = Input.get_axis("ui_left", "ui_right") var y = Input.get_axis("ui_up", "ui_down") var direction = Vector2(x, y) # マウスのクリック位置から方向を得る if Input.is_mouse_button_pressed(MouseButton.MOUSE_BUTTON_LEFT): var m_pos = get_viewport().get_mouse_position() direction = m_pos - Vector2(size / 2) # 移動があるなら速度を変更、ないなら減衰 if direction.length() > 0: velocity = direction.normalized() * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) velocity.y = move_toward(velocity.y, 0, SPEED) # 自動移動 move_and_slide() # 衝突の検出 #var collider = get_last_slide_collision() #if collider: # print("Collider Name: %s" % collider.get_collider().name)
新しい内容が出てきているので、1つずつ解説していきます。
スクリプトの解説
まずはconst
です。定数を作ります。
const SPEED = 150.0
続いて@onready
アノテーションです。このアノテーションが付いた変数の宣言は、_ready
関数が実行される直前に行われます。そのため、ノードツリーにぶら下がった状態でのビューポートサイズなどを得ることができます。
@onready var size = get_viewport_rect().size
_ready
関数では、「AnimatedSprite2D」のアニメーションを開始します。
func _ready() -> void: $AnimatedSprite2D.play()
_physics_process
関数は初めて出てきました。この関数は、プロジェクト設定のFPS(フレーム・パー・セコンド)に合わせて、一定の間隔で呼び出されます。
func _physics_process(_delta: float) -> void:
この呼び出し間隔は_process
関数よりも正確です。_process
関数は描画に合わせて呼び出されるため、性能の低い実行環境では呼び出し回数が減ります。
方向キーからの入力は、次のようなスクリプトで得られます。左右で1つの軸、上下で1つの軸として値を得て、Vector2
を作成します。
# キー入力から方向を得る var x = Input.get_axis("ui_left", "ui_right") var y = Input.get_axis("ui_up", "ui_down") var direction = Vector2(x, y)
少し注意点を述べます。
キー入力は、ゲーム画面にフォーカスが当たっている時しか得られません。
そして、実行時に表示されるデバッグ用のUIが付いたウィンドウと、ゲーム画面は異なる画面です。重ねて表示してあるだけで別のウィンドウです。

外側のウィンドウにフォーカスが当たっている時は、内側のウィンドウでキー操作ができません。ゲーム画面を一度クリックして、ゲーム画面にフォーカスを合わせてからキー操作をしてください。
次に、マウスが画面のどこをクリックしているかで、移動方向を得る処理です。
# マウスのクリック位置から方向を得る if Input.is_mouse_button_pressed(MouseButton.MOUSE_BUTTON_LEFT): var m_pos = get_viewport().get_mouse_position() direction = m_pos - Vector2(size / 2)
ここでは、ビューポートの中心からの方向で、移動方向を計算しています。

こうした処理にしているのは理由があります。このあと、プレイヤーが移動する代わりにカメラを移動させます。そして、プレイヤーは中央に留まったままにします。そのため、中心に対するクリック位置で、移動方向を計算しています。
さて、スクリプトを見ていきましょう。スクリプトはそれほど複雑ではありません。
最初のif
文で、マウスの左ボタンが押されているかを判定します。次の行では、ビューポート上のマウスの位置を得ます。
最後の行のVector2(size / 2)
は少し説明が必要です。冒頭のget_viewport_rect().size
で得た値はVector2i
(整数のVector)です。get_viewport().get_mouse_position()
で得た値はVector2
(小数点数のVector)です。
そのままでは計算できないので、Vector2
にしてから計算しています。
次は速度の変更です。
# 移動があるなら速度を変更、ないなら減衰 if direction.length() > 0: velocity = direction.normalized() * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) velocity.y = move_toward(velocity.y, 0, SPEED)
方向を表すベクトルを正規化してSPEED
を掛けて、「CharacterBody2D」のvelocity
(速度)として設定します。
また、キー操作もマウス操作もない場合は、0に近づけるように速度を減衰させます。
move_toward
関数は、第1引数から第2引数に向かって、第3引数の値だけ数値を変化させます。この戻り値は、第2引数を超えて変化することはないです。
自動移動と衝突の検出
「CharacterBody2D」が便利なのは、速度のベクトルに合わせて移動を自動で行い、衝突の検出もできることです。
移動はmove_and_slide
関数を実行するだけで終わりです。障害物があれば、きちんと止まります。
# 自動移動 move_and_slide()
衝突の検出はget_last_slide_collision
関数で行えます。今回は使用していないのでコメントアウトしていますが、コメントを解除すれば、壁に衝突するたびに衝突相手を出力します。
# 衝突の検出 #var collider = get_last_slide_collision() #if collider: # print("Collider Name: %s" % collider.get_collider().name)
実行確認
player.tscn
を開いた状態で、「F6」を押すか、画面右上の「カチンコの中に▶のアイコン」(現在のシーンを実行)ボタンを押してください。
左上隅にプレイヤーの画像が表示されてアニメーションします。キーボードの操作か、マウスのクリックでプレイヤーを移動できます。
マウスによる操作は、プレイヤーに対してのクリック位置ではなく、画面中央に対してのクリック位置なので注意が必要です。

もし、キーボードでもマウスでも動かせない場合は、デバッグウィンドウの左上にある「入力」ボタンがオンになっているか確認してください。このボタンがオンになっていないと、マウスやキーボードによる操作はできません。
何かの拍子に操作をしてしまい、隣の「2D」が選択状態になっていることもあります。