スクリプトごと使いまわしできる 数字ボタン その1:ベースボタンの作り方
こんな感じのボタンを作る方法をメモ。
主な機能は、
・上をクリックしたら1ずつ減算し、下をクリックしたら1ずつ加算する。
・長押しすることで、数字を送りつづける。
・Enterボタンで判定。
ボタンをPrefabにして、それを使いまわしすればいいんだけど、毎回、桁数や答えが違うから、その都度スクリプトを書いてアタッチするのは、正直めんどくさい。
ということで、prefabのインスペクターで、設定(変数値)を変えるだけで使えるボタンを作って見た。
長くなるので、その1ではスクリプトを含めたベースボタンの作り方をメモ。
1:ボタンを作る
配置はこんな感じ。
mask,Text0,Text1,Text2の名前はスクリプトから参照するので変更不可。
NumberButtonは、ButtonじゃなくてImageで背景画像を設定しておく。
Text0〜Text2は、左から順に並べる。
9 ← Text0の数字 = 保管する数字
0 ← Text1の数字 = 現在の数字
1 ← Text2の数字
画像より少しはみ出るように並べて、3つのテキストにマスクをかける。
↓Text0の位置になる。
↓マスクの領域。
クリックポイントは、指でタップするので、少し大きめに取っておく。
↓減算ボタン
↓加算ボタン
このボタンを作成し、とりあえずPrefabにしておく。
2:Global(シングルトンクラス)に、入力された数字を保管するための変数を作る
入力された数字を保持しておけば、再表示のときに再現できるので、そのための変数を作成する。
同じシーン内で呼び出すだけなので、シングルトンクラスじゃなくてもステージ上で保持できればOK。
中身はスクリプトで追加していくので、空のままで初期化だけしておく。
[HideInInspector] public Dictionary<string,int[]> NumberButtonDictionary = new Dictionary<string,int[]> { };
string(キー) = 識別用
int[] (値) = 各ボタンの一番上のテキストの数字 長さは桁数に合わせる。
3:ボタンにアタッチするクラスを作成する
スクリプトの説明は後ほど。
完成スクリプト
using UnityEngine; using System.Collections; using UnityEngine.UI; public class NumberButton : MonoBehaviour { [SerializeField][Header ("答え")]string answer; [SerializeField][Header ("ボタン識別番号 0〜")]int btnNumber; [SerializeField][Header ("長押し判定するまでの秒数")]float longPress = 0.5f; [SerializeField][Header ("文字を送る速度")]float speed = 0.2f; [SerializeField][Header ("Dictionary Key")]string keyName; //3つのテキスト Text[] texts; //長押しかどうか bool flag = false; //Updateの待機時間カウント用 float passtime; //加算ボタンを押したかどうか bool next = false; void Awake () { //テキストの取得 texts = new Text[3]; for (int i = 0; i < texts.Length; i++) { texts [i] = transform.Find ("mask/Text" + i).GetComponent<Text> (); } //初期化 passtime = longPress; } void Start () { //Dictionaryに追加 if (!Global.instance.NumberButtonDictionary.ContainsKey (keyName)) { int[] array = new int[answer.Length]; for (int i = 0; i < array.Length; i++) { array [i] = 9; } Global.instance.NumberButtonDictionary.Add (keyName, array); } //テキストの初期表示 int first = Global.instance.NumberButtonDictionary [keyName] [btnNumber]; for (int i = 0; i < texts.Length; i++) { texts [i].text = first.ToString (); first++; if (first == 10) { first = 0; } } } void Update () { if (flag) { passtime -= Time.deltaTime; if (passtime <= 0.0) { passtime = speed; SetNumber (); } } } public void OnDown (bool nextFlag) { flag = true; next = nextFlag; SetNumber (); //効果音 AudioManager.instance.PlaySE (0); } public void OnUp () { flag = false; passtime = longPress; next = false; } void SetNumber () { if (next) { int value = int.Parse (texts [0].text); for (int i = 0; i < texts.Length; i++) { value++; if (value == 10) { value = 0; } texts [i].text = value.ToString (); if (i == 0) { Global.instance.NumberButtonDictionary [keyName] [btnNumber] = value; } } } else { int value = int.Parse (texts [2].text); for (int i = texts.Length - 1; i >= 0; i--) { value--; if (value < 0) { value = 9; } texts [i].text = value.ToString (); if (i == 0) { Global.instance.NumberButtonDictionary [keyName] [btnNumber] = value; } } } } public bool OnEnter () { bool ans = false; string str = ""; //効果音 AudioManager.instance.PlaySE (0); foreach (int value in Global.instance.NumberButtonDictionary [keyName]) { int num = value + 1; if (num == 10) { num = 0; } str += num.ToString (); } if (answer == str) { ans = true; } return ans; } }
4:ボタンにアタッチする
手順1のボタンに、手順3のクラスをアタッチする。
長押し判定する秒数と、文字を送る速度を設定する。
それぞれ、数値が大きいほうが遅くなる。1秒=1.0f
それ以外は、実際に使うときに設定する。
5:ボタンイベントを設定する
ボタンにOnDown()とOnUp()を追加する。
OnDown()に、加算するかどうかをチェックする引数があるので、加算する場合はチェックを入れる。
ボタン上部に配置した減算ボタン
下の加算ボタン
この状態で、一旦prefabを保存する。
続きは、その2で。