前提・実現したいこと
UIのボタンのカーソルを思った通りに動かしたいです。
しかしいくつかの障害がありうまくいかず、また考案した方法にも不安があるので相談させてくださいませ。
実現したい動きは以下の通りです。
そして、上部の五つのボタンを選択している際は、これ以上上にボタンはないので上ボタンの反応をなくしたいです。
発生している問題・エラーメッセージ
メニューのボタンのループと上ボタンの問題については最初Explicitのナビゲーションを用いることで実現できました。
しかしメニュー表示選択のボタン(上に六つ並んだ四角いボタン)からスクロール画面に表示されているグリッドに飛ぶことが不可能になったのでこの方法での実装を断念しました。
そして不可能になった理由についてですが、このスクロールはEnhancedScrollerというセルをプレハブとして設定しておきそれを使いまわすことでスクロール画面を作るという仕組みのアセットで作られています。
ゆえにシーンのヒエラルキーからExplicitに移動したいセルを指定しても下記の画像のようにMissingとなってしまうのです。
ゆえに、メニューの表示選択ボタンからセルにとぶために自動で飛べる場所を都度設定してくれるオートマチックにナビゲーションの設定を変えざるを得ず、ループと上のみを無効化することができなくなりました。
また、セルから特定のボタンに戻るという動作についても、このプレハブの仕様が壁になりました。
つまり無数に並ぶセルがすべて一つのプレハブの複製であるために、個別のセルにExplicitで移動先を設定して一番上のセルだけ特定のボタンと結びつけるというようなことができませんでした。
また、これは実際に動かした際のセルの様子です。
試したこと
上だけ停止したりループさせることをこの条件で実現するために、僕は以下のようなコードでUIを制御しようとしました。
C#
1 if(selectButtom == eqButton) 2 {//セレクトしているボタンが左端のボタンの時 3 if(verticalKey == 1) 4 { 5 verticalKey = 0.0f; 6 //上ボタン無効化。全部のボタン選択時に効力を発揮するよう置いている。 7 8 } 9 10 if (horizontalKey == -1) 11 { 12 selectButtom = systemButton; 13 //左端でさらに左を押すと右端のボタンが選択されるようになる 14 } 15 16 eqWindow.SetActive(true); 17 useWindow.SetActive(false); 18 keyWindow.SetActive(false); 19 magicWindow.SetActive(false); 20 libraryWindow.SetActive(false); 21 systemWindow.SetActive(false); 22 //表示するUIの選択 23 }
しかしStandaloneInputModuleとEventSystemの挙動が優先されてしまうようで改善はしませんでした。(VerticalKeyに至ってはただの変数ですから当然ですね。変なコードですみません)
次に、オートマチックにした上でStandaloneInputModuleのスクリプト本体を改変し、特定の場合の上入力を無効化し、さらに左端にいるときは左入力を、右端にいるときは右入力を、それぞれ無効化して
C#
1 if (horizontalKey == -1) 2 { 3 selectButtom = systemButton; 4 //左端でさらに左を押すと右端のボタンが選択されるようになる 5 }
このコードの効果で飛ばそうかとも思いましたがUNITYのコンポーネントをいじることへの恐怖が強くできていません。
それから上ボタンの封印については上を押している間はEventSystem自体無効化することで封印できないだろうかとも考えました。
果たしてこの方法は正しいのでしょうか。また、もっといい方法があったりするのでしょうか。
また、特定のボタンにもどる方法についてはすべてのセルを選択中に戻りたいボタン以外のボタンのButtonコンポーネントを無効化し、特定のボタンに戻ったらほかを再び有効にする方法を考え付きました。
これなら消去法でひとつのボタンに戻れるのではないかと考えた次第です。
しかしもっといい方法があればどうかご教授ください。
よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
Unity 2019 3,7f1
EnhancedScroller
長々とお付き合いさせてしまいましてすみません
C#
1using UnityEngine; 2using UnityEngine.UI; 3#if UNITY_EDITOR 4//Unityエディタのみで実行したい処理を記述。実行時には無効 5using UnityEditor; 6using UnityEditor.UI; 7#endif 8 9public class HorizontalExplicitNavigationButton : Button 10{ 11 [SerializeField] private Selectable selectOnLeft; 12 //左で選択するobject 13 [SerializeField] private Selectable selectOnRight; 14 //右で選択するobject 15 16 /// <inheritdoc /> 17 public override Selectable FindSelectableOnUp() 18 { 19 return null; 20 //上は選択できないよう 21 22 } 23 24 /// <inheritdoc /> 25 public override Selectable FindSelectableOnLeft() 26 { 27 return this.selectOnLeft; 28 //選択するオブジェクトを渡す 29 } 30 31 /// <inheritdoc /> 32 public override Selectable FindSelectableOnRight() 33 { 34 return this.selectOnRight; 35 //選択するオブジェクトを渡す 36 } 37} 38#if UNITY_EDITOR 39//Unityエディタのみで実行したい処理を記述 40[CustomEditor(typeof(HorizontalExplicitNavigationButton), true)] 41//改造するエディタのスクリプトを選択 42[CanEditMultipleObjects] 43 44public class HorizontalExplicitNavigationButtonEditor : ButtonEditor 45{ 46 private SerializedProperty selectOnLeftProperty; 47 //Editor上で表示できるプロパティを設定? 48 private SerializedProperty selectOnRightProperty; 49 //同上 50 51 //UIの書式というか形?外観?をButtonEditor.OnInspectorGuiから継承? 52 /// <inheritdoc /> 53 public override void OnInspectorGUI() 54 { 55 base.OnInspectorGUI(); 56 //カスタムエディタを作るメソッド 57 (this.target as Selectable).navigation = Navigation.defaultNavigation; 58 //Editor型のtargetオブジェクトをSelectable型にキャストし、Navigation型のdefauitNavigationに代入。 59 //つまりインスペクタにSelectable型を含むゲームオブジェクトを入れたらその情報をやり取りしてくれる? 60 61 this.serializedObject.Update(); 62 //表示されるオブジェクトの形式を更新する 63 EditorGUILayout.PropertyField(this.selectOnLeftProperty); 64 EditorGUILayout.PropertyField(this.selectOnRightProperty); 65 //SelectedOnleftとRightを表示する 66 this.serializedObject.ApplyModifiedProperties(); 67 //プロパティの変更を適用 68 } 69 70 //UIの書式というか形?外観?をButtonEditor.OnEnableから継承? 71 /// <inheritdoc /> 72 protected override void OnEnable() 73 { 74 base.OnEnable(); 75 //Objectが有効になったら起動 76 this.selectOnLeftProperty = this.serializedObject.FindProperty("selectOnLeft"); 77 this.selectOnRightProperty = this.serializedObject.FindProperty("selectOnRight"); 78 //UIに表示されるプロパティにselectOnLeftとRightとして選択されたものを入れる? 79 } 80} 81#endif 82 83 84
コード全体の解釈としてはボタンコンポーネントのインスペクタを改造して、さらにFindSelectableOnLeft(Right)メソッドが返す値をオーバーライドでこちらの任意のものに指定しているというような感じでしょうか?
また、こちらのHorizontalExplicitNavigationButtonEditorクラスについてですが、カスタムエディタのためのスクリプトであるということが調べた結果わかりました。
そして多くの場合別々のCSファイルに収めているようでしたが、今回はこのままの形で一つのファイルにしていてよろしいのでしょうか?
暗黙の了解で省いたということでしたら無知をお詫びいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/27 10:48
2020/06/27 14:01
2020/06/27 14:43
2020/06/27 16:10
2020/06/27 16:42 編集
2020/06/27 16:53 編集
2020/06/28 01:28
2020/06/28 04:10 編集