TapTapTap!!!(25)~プレイ画面をAndroid 上の画面に納める~ ではTapTapTap!!!(24)の動作結果を元にアプリの修正(画面幅調整)を行った。今回は、TapTapTap!!!(24)の動作結果を元にアプリの修正(文字ボタンサイズ調整)を行っていく。
今回の修正については、ほとんど全改修といってもいいほどの修正になるため、1から順を追って修正を行っていく。また、これを期に多言語(英語のみ)を対応させる仕組みを作りたいと思う。
1.スタート画面の改修
スタート画面の改修では画面に表示しているオブジェクトをすべて作り直していくパーツとしては以下の通り。詳しくは画面と合わせて確認してほしい。
- ステータスバー
- スタートパネル
1-1.ステータスバーを回収する
ステータスバーの改修では一旦すべてのオブジェクトを削除してからしようと思う。ステータスバーはすべてキャンバスの配下に配置するようにして完全に入れ子構造になるように変更した。その後、Canvas の設定を行った。行った内容は [Inspector] > [Canvas] > [Render Mode] のコンボボックスを「Screen Space – Overlay」から「Screen Space – Camera」に変更した。
それぞれの使用感の違いは以下の通り。
- 「Screen Space – Overlay」:
カメラの位置などに関係なく画面上に上書きする。
- 「Screen Space – Camera」
カメラの位置を基準に画面上に写す。
今回はライフの表示に「Sphere」を使用しているのでカメラの位置情報が必要となるためこちらを採用した。その際、描画するカメラを選択するのだが今回はデフォルトで搭載されている「Main Camera」上に描画することにする。
カメラを設定する理由は憶測となってしまうが、ミニマップ等表示する際にミニマップ上に表示されないようにするためであろう。
次に [Inspector] > [Canvas Scaler] > [UI Scale Mode] のコンボボックスを「 Constant Pixel Size」から「Scale With Screen Size」に変更する。Unity のドキュメントを見るとこれで自動的にスクリーンサイズに合わせてくれるらしい。
それぞれの変更結果画面は以下の通り。
1-2.スタートパネルを回収する
スタートパネルは以下の赤枠の通りに変更する。1-1.で 「Canvas」へ行った変更が正しければこれだけで問題は無いはず。
1-3.設定パネルを設置する(ハリボテ)
設定用パネルを設置し多言語化対応を行う。今回は、内部的な実装は行わずに UI の設置のみ行う。
1-4.スクリプトを設定する
今までは EventSystem にあれやこれやと設定していたが、今回から空の「Game Object」を「Main」という名称で作成し、スクリプトの開始は必ずここから始める用に設定する。その後は以下に示すとおり、「EventSystem」のFirst Selected に設定する。
Main の処理については以下の通りで、GooglePlayGames の開始とライフ表示機能の初期化、最高レベルの表示を行う。
[cce_csharp]using UnityEngine; public class Main : MonoBehaviour { /// <summary> /// ゲーム開始に合わせて実行される。 /// Start画面のメインスクリプト /// </summary> void Start() { StartGooglePlayGames(); // ライフ表示機能の初期化 FindObjectOfType<LifeViewer>().Init(); // 最高レベルの表示 FindObjectOfType<HeighestLevel>().ShowHighestLevel(); } /// <summary> /// GooglePlayGames の開始 /// </summary> private void StartGooglePlayGames() { // Google Play Games を有効化 GooglePlayGames.PlayGamesPlatform.Activate(); // Google Play Games へのログイン Social.localUser.Authenticate((bool success) => { // ToDo }); } }[/cce_csharp]
ライフ管理については以下のように「Life Panel」で設定するよう処理を変更する。「LifeManager」と「LifeViewer」には変更を加えない。
最高レベルを表示していた「MaxLevel」は「HeighestLevel」に名称を変更した。「HeighestLevel」は「HighestLevelText」にドラッグアンドドロップ」した後、以下のように最高レベルを表示するだけの機能となった。
[cce_csharp]using UnityEngine; using UnityEngine.UI; public class HeighestLevel : MonoBehaviour { /// <summary> /// 最高レベル表示用テキスト /// </summary> [SerializeField] private Text maxLevel; /// <summary> /// 最高レベル用テキスト /// </summary> private string maxText = "最高レベル:"; /// <summary> /// 過去最高レベルの表示 /// </summary> public void ShowHighestLevel() { if (PlayerPrefs.HasKey("PlayerData")) { int level = PlayerPrefs.GetInt("PlayerData"); maxLevel.text = maxText + level.ToString(); } else { maxLevel.text = maxText + "-"; } } }[/cce_csharp]
2.プレイ画面の改修
ゲーム画面については「Canvas」については1.で行ったものを同様に適用する。スコアとレベルについては、下部に表示するパネルを追加した。
これだけでは、スコア表示部にもボタンが被ってしまうため、「ButtonManager 」に対して、スコア表示部を除くように処理を加える。
[cce_csharp]using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class ButtonManager : MonoBehaviour { /// <summary> /// 生成するボタンオブジェクト /// </summary> [SerializeField] public GameObject button; /// <summary> /// ボタンやポイントを表示するためのキャンバス /// </summary> [SerializeField] public GameObject canvas; /// <summary> /// ゲームオーバーテキストオブジェクト /// </summary> [SerializeField] public GameObject gameOverText; /// <summary> /// ゲームオーバーテキストオブジェクト /// </summary> [SerializeField] public GameObject returnButtonO; /// <summary> /// ボタン出現時間 /// </summary> public float buttonAppearanceTime; /// <summary> /// ボタン消滅時間 /// </summary> public float buttonExtinctionTime; /// <summary> /// ポイント表示用テキストオブジェクト /// </summary> public Text pointText; /// <summary> /// レベル表示用テキストオブジェクト /// </summary> public Text levelText; /// <summary> /// レベルアップまでの回数 /// </summary> public int levelUp; /// <summary> /// レベルアップ用テキスト /// </summary> public GameObject levelUpText; /// <summary> /// ボタン表示位置(幅)の上下限値の絶対値 /// </summary> private int screenWidth; /// <summary> /// ボタン表示位置(高さ)の上下限値の絶対値 /// </summary> private int screenHeight; /// <summary> /// 連続成功回数 /// </summary> private int succession; /// <summary> /// 連続失敗回数 /// </summary> private int failure; /// <summary> /// ゲームオーバー判定フラグ /// </summary> private bool gameOver = false; /// <summary> /// ボタン出現時のタイムアウト管理 /// </summary> private float timeOut; /// <summary> /// レベルアップまでの回数 /// </summary> private int levelUpCount; /// <summary> /// レベル表示用テキスト /// </summary> private string constLevelText = "Level:"; /// <summary> /// スタート時のレベル /// </summary> private int level = 1; /// <summary> /// パネルの高さ /// </summary> [SerializeField] private GameObject panel; /// <summary> /// パネルの高さ /// </summary> private float panelHeight; /// <summary> /// ゲーム開始時の処理。画面サイズの取得を行う。 /// </summary> void Start() { panelHeight = panel.GetComponent<Image>().transform.lossyScale.y; screenWidth = (Screen.width - 100) - (Screen.width - 100) / 2; screenHeight = (Screen.height - 100) - (Screen.height - 100) / 2; levelText.text = constLevelText + level.ToString(); } /// <summary> /// 逐次更新された際の処理。時間の管理やボタンの生成、ゲームオーバーの判定を逐次行う。 /// </summary> void Update() { timeOut += Time.deltaTime; // timeOut が buttonAppearanceTime を超えたらボタンを出現させる if (!gameOver && buttonAppearanceTime < timeOut && levelUpCount != levelUp) { StartCoroutine("execute"); timeOut = 0; levelUpCount++; } // ポイントが 0 以下になったらゲームオーバー if (!gameOver && FindObjectOfType<Score>().getPoint() <= 0 && levelUpCount != levelUp) { GameObject prefab = (GameObject)Instantiate(gameOverText); prefab.transform.SetParent(canvas.transform, false); if (PlayerPrefs.HasKey("PlayerData")) { int bestLevel = PlayerPrefs.GetInt("PlayerData"); if (bestLevel < level) { PlayerPrefs.SetInt("PlayerData", level); } } else { PlayerPrefs.SetInt("PlayerData", level); } gameOver = true; GameObject returnButton = (GameObject)Instantiate(returnButtonO); returnButton.transform.SetParent(canvas.transform, false); } } public void OnExit() { if (gameOver) { SceneManager.LoadScene("Start"); } } /// <summary> /// ボタンの生成処理。ボタンの生成を行う。 /// </summary> /// <returns>生成されたボタンオブジェクト</returns> private GameObject createButton() { GameObject prefab = (GameObject)Instantiate(button); Vector3 position = new Vector3(Random.Range(-screenWidth, screenWidth), Random.Range(-screenHeight+ panelHeight, screenHeight), 0); prefab.transform.position = position; prefab.transform.SetParent(canvas.transform, false); return prefab; } /// <summary> /// 本ゲームのメイン実行処理。ボタンの生成や点数の加減計算を行う。 /// </summary> /// <returns>IEnumerator オブジェクト</returns> private IEnumerator execute() { GameObject prefab = createButton(); yield return new WaitForSeconds(buttonExtinctionTime); int count; // ボタンタップによってボタンオブジェクtが削除されているときは加点、 // 削除されていなかったときは減点する if (prefab != null) { GameObject.Destroy(prefab); failure--; count = failure; succession = 0; } else { succession++; count = succession; failure = 0; } FindObjectOfType<Score>().addPoint(10 * count); if (levelUpCount == levelUp) { GameObject levelUpObject = (GameObject)Instantiate(levelUpText); levelUpObject.transform.SetParent(canvas.transform, false); yield return new WaitForSeconds(1); GameObject.Destroy(levelUpObject); buttonExtinctionTime /= 4; buttonExtinctionTime *= 3; buttonAppearanceTime /= 4; buttonAppearanceTime *= 3; level++; levelText.text = constLevelText + level.ToString(); levelUpCount = 0; } } }[/cce_csharp]
3.広告画面の改修
こちらについては修正なし。