ご返信いただき誠にありがとうございます。
こちらのサンプルを元に、最終的に望む挙動が実現できました。
上記のサンプルで試してみたところ、私の環境下ではなぜかキャラ移動のためのWASDのWとSで選択肢のナビゲーションが動いてしまったこともあり、最終的にはプロジェクト的にInputSystemを使用してキーを管理したところで、たしかに、キーボードによる操作はプロジェクトごとの仕様で大きく異なることがわかりました。
以下、私の環境下で動くものであることと、コードの内容を理解できているわけではないのですが、
一応、望む挙動を実現できたと思われるコードを超参考レベルで載せておきます。(同じような質問があったように思えましたので)
ただ私の場合では「4方向移動のゲームで会話シーンに宴を使い、会話中もキャラ移動ができるようにしたい」など特殊な仕様が混じっているため参考になるかは全くわかりません…
(完全に無責任なコード掲載ですので、もしやめたほうがいいということであれば、削除します)
【前提】
・InputSystemを使い、キーボードとゲームパッドでも「Selectionの選択肢のナビゲーション」と「文字送り」ができるようにしたかった。
・InputSystemの設定は
ActionMaps - "Player" "UI"
Actions - Player - "Move","Jump","Interact"
UI - "EnterMessage","Select"
でそれぞれ適当に設定していました。
【要点】
・使ったスクリプトは2点で「(Selectionの選択肢のナビゲーションのための)上記サンプルを改造したSelectionKeyboardInput」と「(文字送りのための)CustomAdvUguiManager」
・SelectionKeyboardInputは「InputSystemで設定したもの以外で選択肢のナビゲーションを動かさない」「ActionMapsのPlayerとキーがバッティングするようであれば、UIを優先しPlayerの方を無効にする」などの要素が入っていると思います
・CustomAdvUguiManagerはAdvUiManagerをおそらく継承する形にしている
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using System.Collections;
using UtageExtensions;
namespace Utage
{
public class SelectionKeyboardInput : MonoBehaviour
{
private PlayerControls controls;
private int currentIndex = 0;
AdvEngine Engine => this.GetAdvEngineCacheFindIfMissing(ref engine);
[SerializeField] private AdvEngine engine;
AdvUguiSelectionManager UguiSelectionManager => this.GetComponentCacheInChildren(ref uguiSelectionManager);
[SerializeField] private AdvUguiSelectionManager uguiSelectionManager;
void Awake()
{
controls = new PlayerControls();
controls.UI.Select.performed += OnSelectPerformed;
controls.UI.EnterMessage.performed += OnEnterPerformed;
Engine.SelectionManager.OnBeginWaitInput.AddListener(OnInit);
}
void OnEnable()
{
controls.UI.Enable();
controls.Player.Disable(); // UIを優先し、Playerの入力を無効化
}
void OnDisable()
{
controls.UI.Disable();
controls.Player.Enable(); // UIを抜けたらPlayerの入力を有効化
}
void OnInit(AdvSelectionManager selectionManager)
{
if (UguiSelectionManager.Items.Count <= 0) return;
// UIナビゲーションをInputSystemのみに制限する
EventSystem.current.sendNavigationEvents = false;
currentIndex = 0;
StartCoroutine(SetSelectedButton(UguiSelectionManager.Items[currentIndex]));
}
void OnSelectPerformed(InputAction.CallbackContext context)
{
if (UguiSelectionManager.Items.Count <= 0) return;
Vector2 input = context.ReadValue<Vector2>();
if (Mathf.Abs(input.y) > Mathf.Abs(input.x)) // 上下のみを処理
{
if (input.y > 0) // 上移動
{
currentIndex = Mathf.Max(currentIndex - 1, 0);
}
else if (input.y < 0) // 下移動
{
currentIndex = Mathf.Min(currentIndex + 1, UguiSelectionManager.Items.Count - 1);
}
StartCoroutine(SetSelectedButton(UguiSelectionManager.Items[currentIndex]));
}
}
void OnEnterPerformed(InputAction.CallbackContext context)
{
if (UguiSelectionManager.Items.Count <= 0) return;
GameObject selected = EventSystem.current.currentSelectedGameObject;
if (selected != null)
{
selected.GetComponent<Button>()?.onClick.Invoke();
}
}
private IEnumerator SetSelectedButton(GameObject button)
{
yield return new WaitForEndOfFrame(); // フレーム遅延を挟む
EventSystem.current.SetSelectedGameObject(null); // 既存の選択をクリア
EventSystem.current.SetSelectedGameObject(button); // ボタンを選択
ExecuteEvents.Execute(button, new BaseEventData(EventSystem.current), ExecuteEvents.selectHandler); // UI フォーカス適用
}
}
}
using UnityEngine;
using UnityEngine.InputSystem;
using Utage;
public class CustomAdvUguiManager : AdvUguiManager
{
private PlayerControls playerControls;
private void Awake()
{
// InputSystem の PlayerControls を初期化
playerControls = new PlayerControls();
// UI マップの EnterMessage アクションにイベントを設定
playerControls.UI.EnterMessage.performed += OnEnterMessage;
// 入力を有効化
playerControls.Enable();
}
private void OnEnterMessage(InputAction.CallbackContext context)
{
// Enterキーでメッセージ送りを行う
if (Status == UiStatus.Default && IsShowingMessageWindow)
{
Engine.Page.InputSendMessage();
}
}
private void OnDestroy()
{
// InputSystem のイベントを解除
if (playerControls != null)
{
playerControls.UI.EnterMessage.performed -= OnEnterMessage;
playerControls.Disable();
}
}
}
SelectionKeyboardInput は上記サンプルと同じ使用方法
CustomAdvUguiManager はAdvEngine-UIのAdvUguiManagerをRemoveComponentしてアタッチ
です。
2025年2月5日水曜日 10:42:15 UTC+9 マッドネスラボ: