SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Godot Engine 2Dゲーム開発入門

【Godot Engine 2Dゲーム制作 Part1】キャラクターを出して動かそう!

Godot Engine 2Dゲーム開発入門 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

プレイヤーのスクリプトを書こう

スクリプトの作成

 続いて「Player」ノードにスクリプトをアタッチします。

 「Player」ノードを右クリックして「スクリプトをアタッチ」を選択します。「ノードにスクリプトをアタッチする」ダイアログが表示されますので「テンプレート」にチェックを入れて、そのまま「作成」ボタンを押します。

 res://scn/player/player.gdと保存されたはずです。

 このplayer.gdをScriptビューで開き、次のようにスクリプトを書き換えます。

player.gd
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」が選択状態になっていることもあります。

次のページ
迷路シーンを作ろう

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Godot Engine 2Dゲーム開発入門連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21371 2025/06/19 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング