キー操作でUIのナビゲーションをループさせる

概要

ボタン

キーの上下でカーソル移動させる際、上図のようにボタンが並んでいるときに最上部から最下部にループしたいケースがあります。
UIコンポーネントには下図のようにナビゲーションの設定項目があるのですが、これらを設定しても自動でループの表現はできません。
Navigation項目をExplicitに設定して各遷移先を明示的に指定すれば可能ですが、手間なので自動で設定するようにします。

ナビゲーション設定

ナビゲーションを自動設定

ヒエラルキー

レイアウトグループを使うことを考えると、ヒエラルキーの順番とボタンの順番は一致しているので、この順番どおりにナビゲーションを設定します。
以下のようなコードを書いて、ボタンの親のオブジェクトにつけます(上図でいうCanvas)。
ボタンなどはSelectableクラスを継承しているのでこれを取得して、全てにナビゲーションモードをExplicitにして遷移先を設定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class LoopMenu : MonoBehaviour {
void Start() {
//子のボタンやスライダーなど操作可能なコンポーネントを取得する
var selects = GetComponentsInChildren<Selectable>();
for (var i = 0; i < selects.Length; i++) {
var nav = selects[i].navigation;
nav.mode = Navigation.Mode.Explicit;
nav.selectOnUp = selects[i == 0 ? selects.Length - 1 : i - 1];
nav.selectOnDown = selects[(i + 1) % selects.Length];
selects[i].navigation = nav;
}
}
}

他のケース

例えば、interactableでないボタンは除外する場合は、子のselectableを取得したあとに、以下のようにFilterすれば良いと思います。

selects = selects.Where((s) => s.interactable).ToArray();

また、あまりないと思いますが、ヒエラルキーの順番と一致しない場合はpositionでソートするという方法も考えられます。

使用バージョン

Unity 2019.4.5

Unityカテゴリの記事
Kris' Favorite Assets が便利
TextMeshProのSprite Assetを更新する
UnityPhysicsDebugDraw2D が便利
色管理を考える
Open Recent Scene が便利
細かいTips
ビルドスクリプトを書く
AnimatorのCulling Modeでハマった話
Vectrosityを使ってUGUI上で線や円のアニメーションをする
スプレッドシートからjsonデータを読み込む
ビジュアルノベルアセットFungusにコマンドを追加してカスタマイズする
Skinned Mesh Renderer の Boundsについて
シーンごとにビルド結果の容量を出す
シーンビューにクオリティ設定のスライダーを出すエディタ拡張
ビルド結果のFile headersが大きい理由
フリーのビジュアルノベルアセットFungusを使ってRPGのイベントを作る
Move To View を改良する
フリーのビジュアルノベルアセットのFungusが便利
Visual Studio で保存時にフォーマットする
スプレッドシートからデータを読み込む
Easy Save2 で シリアライズされたクラスを保存する
ShaderでSpriteの色相をシフトする
Sprite、Texture の 色相をシフトする
uGUIのButtonをクリック時にハイライトのままになる
uGUIのCanvas Groupを使って透過処理をしたり、操作を制限する
自作のコンフィグ画面に必要なもの
uGUIでトグルなボタンを作る
uGUI で動的にボタンを作る
Easy Save2 を使ってみる
csv読み込んで ローカライズ
LoadLevelAdditive で共通シーンを加算
画面全体に色をかける
Any State でどこからでも遷移できるようにする
iTween のStop ではまる
sprite の multiple で 境界がおかしくなる
2D画面に線を引く Line Renderer
Renderer の Materials を スクリプトから設定する
背景をスクロールさせる