仮想ジョイスティックを作成する
Godot Engine バージョン4.3
このチュートリアルでは、Godot 4.3 を使用してモバイルゲーム向けの仮想ジョイスティックを作成する方法を解説します。タッチスクリーン対応のシンプルなジョイスティックを設計し、プレイヤーがタッチ操作でキャラクターを移動できる仕組みを学びます。
1. ジョイスティックのUIを準備する
シーン構成
Control
ノードを親に追加。
base
(ジョイスティックの土台)とhandle
(ジョイスティックのハンドル)用にTextureRect
ノードを追加。
ジョイスティックのデザイン
base
に円形の画像を設定して土台をデザインします。
handle
に小さい円形画像を設定します。
2. スクリプトを設定する
親ノード (
Control
) に以下のスクリプトをアタッチします。
extends Control
# ジョイスティック用のUI要素@onready var base = $base@onready var handle = $handle
# ジョイスティックのスケール(画面の高さに基づく)デフォルトは0.33(画面高さの33%)@export_category("画面の高さに基づく")@export_range(0,1) var joystick_scale:float = 0.33
# ジョイスティックの指のインデックス# マルチタッチをサポートするため、画面上の指のインデックスまたはIDを追跡する必要がありますvar joystick_finger_index = 0
# ジョイスティックUIのサイズ変数(_ready関数で設定)var joystick_starting_size: floatvar joystick_handle_starting_size: float
# タッチパッドの指のインデックス# マルチタッチをサポートするため、画面上の指のインデックスまたはIDを追跡する必要がありますvar touch_pad_finger_index = 0
# タッチパッド上の最後の位置を記録するベクトル# 現在位置と最後の位置の差分がタッチパッドの出力になりますvar touch_pad_last_position: Vector2 = Vector2.ZERO
# 正規化されたジョイスティックの最終出力(この値を読み取るには get_joystick() を使用)var joystick: Vector2 = Vector2.ZERO
# タッチパッドの最終出力(この値を読み取るには get_touchpad_delta() を使用)var touchpad_delta: Vector2 = Vector2.ZERO
# ウィンドウサイズ変数var window_width = 0var window_height = 0
func _ready(): # 画面サイズの取得 window_width = get_viewport().content_scale_size.x window_height = get_viewport().content_scale_size.y # ジョイスティックのベースとハンドルのサイズを画面の高さとスケールに基づいて設定 joystick_starting_size = window_height * joystick_scale joystick_handle_starting_size = joystick_starting_size / 2 # ジョイスティックのUI要素のサイズを設定 base.size = Vector2(joystick_starting_size, joystick_starting_size) handle.size = Vector2(joystick_handle_starting_size, joystick_handle_starting_size)
func _input(event): # 入力がタッチかどうかを確認 if event is InputEventScreenTouch: # タッチ開始時の処理 if event.pressed: # タッチが画面の左側で、ジョイスティックがまだアクティブでない場合を確認 if event.position.x * get_viewport().get_screen_transform().x.x < window_width / 2 and !joystick_finger_index: # ジョイスティックのタッチを開始 base.show() handle.show() base.position = event.position - (base.size / 2) handle.position = event.position - (base.size / 2) + (handle.size / 2) joystick_finger_index = event.index else: # タッチパッドのタッチを開始 touch_pad_last_position = event.position touch_pad_finger_index = event.index else: # タッチ終了時の処理 if event.index == joystick_finger_index: # ジョイスティックタッチ終了時にUIを非表示にしてジョイスティックをリセット base.hide() handle.hide() joystick = Vector2.ZERO joystick_finger_index = null if event.index == touch_pad_finger_index: # タッチパッドのタッチ終了時 touch_pad_finger_index = null # 入力がタッチドラッグかどうかを確認 if event is InputEventScreenDrag: if event.index == joystick_finger_index: # ジョイスティックのドラッグ処理 var handle_pos = event.position var handle_normalized = event.position handle_pos -= handle.size / 2 handle_normalized -= (base.position + base.size / 2) handle_normalized = handle_normalized / (base.size / 2) joystick = handle_normalized / (base.size / 2) handle_normalized = handle_normalized.normalized() handle_normalized = handle_normalized * (base.size / 2) handle_normalized += (base.position + base.size / 2) handle_normalized -= handle.size / 2 # タッチがジョイスティックのベース外に移動した場合、ハンドルの正規化された位置を使用 # これにより、ジョイスティックのハンドルがベースの外に出ないようにする if event.position.distance_to(base.position + base.size / 2) < base.size.x / 2: handle.position = handle_pos else: handle.position = handle_normalized elif event.index == touch_pad_finger_index: # タッチパッドのドラッグ処理 var movement = event.position - touch_pad_last_position touch_pad_last_position = event.position touchpad_delta += movement
# ジョイスティック値のゲッターfunc get_joystick() -> Vector2: return joystick
# タッチパッド値のゲッター# 重要: タッチパッド値を取得する際は必ず get_touchpad_delta 関数を使用# 入力関数と更新関数が同期していない場合があるため、位置の変化を一時的に保存し、# データが失われないようにするfunc get_touchpad_delta() -> Vector2: var touchpad_delta_return = touchpad_delta touchpad_delta = Vector2.ZERO return touchpad_delta_return
3. 結果を確認する
シーンを実行し、画面の左半分をタッチするとジョイスティックが表示されます。
指をドラッグするとハンドルが動き、
get_joystick()
を使って方向ベクトルが取得できます。