はじめに
NGUIでボタン機能を実装するUIButtonですが、シーンの移動中など、
押せてはいけない場面というのが多々あります。
今までは〇〇ButtonManagerみたいなのに管理させていたのですが、
各ボタン自身が自分が押せるかどうかを判定したら楽じゃね?と思いやってみたら
予想以上に楽だったのでご紹介。
押せるかどうかの判定だけでなく、押した時の色やらのボタン設定もやるようにしました。
UIButtonAssistant.cs
とりあえずコードから!
これをUIButtonが付いているGameObjectに一緒に付ければ、
シーン移動中は無効にしてくれるわ、
ボタン押した時の色を設定してくれるわ、
押した時のSEを設定してくれるわ
でかなり楽に…!
コード説明
まず諸々がprotectedになっているのは継承前提のクラスだからです。
シーン移動以外で無効にしないボタンはそのまま使いますけどね。
ボタンの色
各状態のボタン色をAwakeで設定しています
- _normalColor 通常時の色
- _hoverColor カーソルがボタンの上に来た時の色(スマホじゃ関係ない)
- _pressedColor ボタンを押した時の色
- _disabledColor ボタンが無効になっているときの色
_disabledColorが白なのは、無効時に毎回色変わるのが結構目に五月蝿いなーと思ったからです。
まぁボタンの種類によりけりといった感じで。
SE
SEやBGMなどは全てAudioManagerが管理するようにしてるため、
UIPlay Soundは使っていません。詳しくは以下の記事を参照の事。
_seNameにボタンのSE名を登録しているので、ボタン毎にSEを変えたい場合は継承して、
Awakeで書き換える感じにしています。
PlaySE()がSEを鳴らすメソッドですが、Inspector上で登録するのではなく、Awakeで
クリックした時に(onClick)SEを鳴らすメソッド(PlaySE)を実行するように登録しています。
//ボタンを押した時のSEが鳴るようにメソッドを登録 EventDelegate.Add (GetComponent<UIButton> ().onClick, this.PlaySE);
これで、毎度SE設定する面倒さが解消…!
色が変わる時間
ボタンの色が変わるまでの時間をTransitionで設定できるのですが、
デフォルトの0.2秒が長く感じたので基本0.05秒に設定しています。
ここは継承して変える事は無さそうですが念のためprotected。
ボタン無効判定&設定
シーンの移動をSceneManagerに管理させており、
SceneManager.Instance.IsFadingでシーン移動中かを判定出来るようにしているため、
ボタンを押せるかどうかの_isEnabledに!SceneManager.Instance.IsFading
を設定する事で、シーンの移動中はボタンを押せないようにしています。
継承先でボタンを押せるかどうかに他の条件を付ける場合は以下のようにします。
protected override void Update () { base.Update (); _isEnabled = _isEnabled && 他の条件; }
Updateでボタンが押せるか判定した後、LateUpdateで実際にボタンの有効無効を設定しています。
Inspector上で言う、UIButtonのチェックを付けたり外したりしてる感じです。
UpdateとLateUpdateで分けている理由は、
基本的にボタンの判定は継承先で条件が追加され、有効無効の設定は変わらないと思ったからです。
LateUpdateはprivateで良かったかも…。
ChildLabelとChildSprite
UIButtonはTweenTargetにしているモノの色しか変わりません。
TweenTargetは基本的にボタンのスプライトなので、
それ以外のラベルやらボタン以外のスプライト(通知アイコン)やらは、
ボタンを押した時にもそのままの色で、浮いてしまうのが気になります。
なので、最初にスプライトやラベルとその初期の色をChildLabel、ChildSpriteとして保持し、
TweenTargetの色に各々の初期色を掛け合わせる事で、
同じように色が変化し、浮かないようにしています。
実際にこの処理をしたものと、していないものの画像が以下になります。
- 左 :押す前の状態
- 中央:未処理の押した後、ボタンだけ暗い
- 右 :処理済の押した後、ボタンに合わせて他も暗く
機能としては特に変化は無いのですが、気になっていたので実装してみました。
UIButtonAssistantが付いているかのチェック
全てのUIButtonにUIButtonAssistantが付いているようにしたいのですが、
[RequireComponent(typeof(UIButtonAssistant))]
とUIButtonに書いてしまうと、継承させたクラスを付けようとしてたのに違うのが付いてる!
みたいになりかねなかったので、UIButtonのOnEnableに以下のようなコードを書いています。
if(!GetComponent<UIButtonAssistant>()){ Debug.Log(gameObject.name + "にUIButtonAssistantが無いよ!"); }
これで付け忘れも解消…!
おわりに
紹介しといて何ですが、このやり方は楽ですが、良い方法なのかは分かりません。
ボタンというかUI全般はどう管理して良いのかいまだに悩み中…