在AGM里如何该如何实现适配真实的手柄摇杆操作方向?

皆様こんにちは。コントローラーのスティックマッピングについて皆様と議論したいと考えています。アクションゲームメーカーである以上、アクションゲーム制作において、皆様もコントローラーでのプレイを望まれるでしょう。優れた操作性はゲームに非常に大きな助けとなります。

以前、メールでMr.BAZと少し議論したことがあります。

現在のAGMにおける入力マッピングでは、スティックはボタンのマッピングとして扱われており、実際のスティック入力ではありません。そのため、マッピング内でデッドゾーン値を設定しても、いかなる値を設定しても無効となってしまいます。これはスティック操作の微妙な変化を認識させることができないことを意味し、非常に問題です。

例を挙げますと、

スティックをわずかに動かすだけで即座にボタンがトリガーされてしまいます。どの程度の押し込み範囲で認識させるかというデッドゾーン閾値を設定することができません。

もう一つ最も深刻な問題は、キーの重複(クロス入力)が非常に激しいことです。スティックをわずかに傾けるだけで「下」の入力が認識されてしまいます。

これはアクションゲームにとって全く受け入れがたい状況です。

私は多くの横スクロールアクションゲームをテストしましたが、大半のゲームでは、斜め下方向にこれだけの角度まで傾けて初めて「下」の入力が認識されます。これは非常に合理的で、直感的な感覚にも合致しています。

現在のAGMのマッピング機能では、この基本的な機能を簡単に実現することができません。そのため、GDスクリプトを使用して実際のスティック操作を実現しようと考えました。

しかし、その過程で多くの問題に直面しました。通常、Godot内でGDスクリプトでスティックを設定するには、プレイヤーの基盤コードにバインドする必要がありますが、私のプレイヤーは完全にVSスクリプトで制作されています。キャラクターをスティックの上下左右移動に結びつける方法がまだ見つかっていません。どのように実行すればよいでしょうか?

自分自身では解決できず、ここで皆様と議論したいと考えています。
AGMにおいて、スティックを実際に適切に動作させる方法はないでしょうか。これはアクションゲームにとって非常に重要な問題です。

GD設定用のジョイスティックコードを添付します。システム側ではジョイスティックの存在は認識できますが、それをプレイヤーの入力マッピングにバインドする方法はまた別の問題です。さらに、バインドした後にAGMのデフォルト動作と同様にキー入力として扱われてしまうかどうかは不明です··· :crying_cat:

extends Node

@export var dead_zone: float = 0.08
@export var diagonal_threshold: float = 0.5

var joy_id: int = -1

func _ready():
	_scan_joypad()

func _scan_joypad():
	var joy_list = Input.get_connected_joypads()
	if not joy_list.is_empty():
		joy_id = joy_list[0]

func _process(_delta):
	if joy_id == -1:
		_scan_joypad()
		return

	var raw_x = Input.get_joy_axis(joy_id, 0)
	var raw_y = Input.get_joy_axis(joy_id, 1)
	var stick_vec = Vector2(raw_x, raw_y)

	# 毎フレームすべての入力を解放
	Input.action_release("UP")
	Input.action_release("DOWN")
	Input.action_release("LEFT")
	Input.action_release("RIGHT")

	if stick_vec.length() < dead_zone:
		return

	var normal = stick_vec.normalized()
	var strength = stick_vec.length()

	if strength >= diagonal_threshold:
		if abs(normal.y) > abs(normal.x):
			if normal.y < 0:
				Input.action_press("UP", true)
			else:
				Input.action_press("DOWN", true)
		else:
			if normal.x < 0:
				Input.action_press("LEFT", true)
			else:
				Input.action_press("RIGHT", true)

func bind_joy_device(target_id: int):
	joy_id = target_id