節電鯖民の遊び場

03-背景とカウンタを用意する

最終更新:

mcforum

- view
メンバー限定 登録/ログイン

目次


できたもの



前提


素材集め

+ 詳細を開く

背景映像を貼りつける

+ 詳細を開く
  • ヒエラルキーで VideoPlayer を追加
  • 背景videoは適当にAssetsに入れてあるものとする
  • video playerに背景videoファイルを登録して各種設定を実施
    • Video Clip: Assetのvideoファイルをドロップして登録
    • Loop: ループ素材なのでチェックを入れる
    • Render Mode: 背景として流すので"Camera Far Plane" を選択
    • Camera: ヒエラルキーの Main Camera をドロップして登録する
    • Aspect Ratio: 画面の縦横サイズが変わっても背景映像以外が映らないよう"Fit Outside"にしておく。
    • Scene再生ボタンを押して映像が背景に流れていればOK


クリックした回数を表示するカウンタを実装する

仕様

+ 詳細を開く
  • カウンタは画面左上に配置するものとする。
  • 画面サイズが変更されても同じ位置にあって欲しい。
  • クリックしたらクリック回数の数値を更新表示する。


キャンバスとテキストラベルを配置する

+ 詳細を開く

キャンバスの配置

  • まずはヒエラルキーにCanvasを設置する
    • これにより、カメラ(初期設定ではdisplay)に追従するUIの設置場所ができる

  • 初期設定のままでもUI設置は可能だが、設置UIがカメラ座標に追従するよう設定を変更する。
    • Canvas設定の Render Mode を "Screen Space - Camera" に変更する。
    • Render Camera に ヒエラルキーから Main Camera をドロップして登録する。
    • これにより設置UIにColliderをつけた場合にUI以外のオブジェクトとの接触判定が取れるようになる。
      • ※Canvas上でのColliderは次回利用する

テキストラベルの配置

  • クリック数カウントを表示するテキストオブジェクトをCanvasに設置する
    • ヒエラルキーからCanvasを右クリックしてUIのTextMeshProを追加する。
      • 見た目を弄りたいだけなので、ただのTextでも良い
      • TextMeshPro使用する場合は TMP Importer が表示されるので、Import TMP Essentials ボタンでインポートする。

TextMeshProを使用する場合の追加作業

  • フォントを変換してTextMeshProで利用できる形式にする
    • UIで通常のTextを使う場合はこの作業は不要
+ 詳細を開く
  • メニューから TMP の Font Asset Creator を開く
  • 表示されたCreatorで、変換したいフォントのttfファイルを選ぶ
  • 英数字記号のみ変換する場合はそのまま Generate Font Atlas ボタンを押す
    • このとき元のフォントに含まれていない文字は変換に失敗する(詳細は下部のレポートに表示される)
  • それ以外、例えば日本語等が必要な場合には Charactor Set を "Custom Characters" に変更し、表示されたテキストボックスに変換する文字を全て記入しておく。
    • Select Font Asset で適当なFont Assetを選択しておくと、既存の他のFontAssetで対応している文字がCustom Character Listにインポートされるので、それに追加で必要な文字を入れていく。なければ手動で必要な物を入れていく。
    • 変換は同様に Generate Font Atlas ボタンを押すこと。
  • ウインドウサイズを広げると、生成後の文字列が表示される。
  • 生成した文字がぼやけている場合は Atlas Resolution の数値を上げること。
  • Saveを押すと保存ダイアログが表示されるので、Asset/Fonts 等適当なディレクトリを作成して保存する。

  • メモ
    • Canvas Scaler の UI Scale Mode を Scale With Screen Size 等に変更すると Canvas に配置した各アイテムが画面サイズに応じて自動でスケールする。
    • このとき Text Mesh Pro の文字の周りに文字色に近い色で枠ができてしまう事があるが、これはTMPの Face→Dilate を -1 に、Debug Settings の Sharpness を最大値(1)に設定すると改善するが、文字に対するエフェクトが掛からなくなってしまうので注意
      • Sharpness だけ 1 にして、Dilate を -0.5 ぐらいにすると妥協できるかも

テキストラベルの設定

  • TextのインスペクターからRect TransformのAnchor Presetsを選択する。
    • 今回はCanvas(Camera)の左上に張り付かせたいのでtop/leftを選択する。
    • これで画面サイズを変更した場合も、テキスト座標は左上を基準に自動で調整される。

  • 初期表示するテキストを配置する
    • テキストボックスに表示文字列を入力する
    • 文字数が増えて幅や高さが大きくなった場合、どの方向に拡張されるかはAlignmentの設定で調整すること。
    • Font Asset に Font Asset Creator で作成した Font Asset を指定する。
      • もし通常の Text の場合は Font の設定で ttf ファイル等を選択する
    • Vertex Colot (Textの場合は Color)でフォントの色を指定する。
      • 背景画像や映像を用いている場合は、それにあった色にする。


テキストを更新するスクリプトを実装する

+ 詳細を開く

仕様

  • 今回はカウンタ値を使用するのはテキストラベルだけであるが、今後カウンタ値を使用する機能が増える事を見越して以下の仕様で実装する。
    • Sceneを跨ぐ永続オブジェクトにゲーム全体で使用する値(今回のカウンタ値など)を持たせる。
      • GameController クラス/オブジェクトとし、ヒエラルキーのルートに配置する。
    • クリックした場合、GameController にカウンタ値のインクリメントを指示する
    • GameController へは public List を用いてカウンタ値を利用するクラスオブジェクトの登録を行う。
      • ※将来的に動的に登録する関数を設けるかどうかは検討する。
    • GameController はカウンタ値を利用するクラスオブジェクト全てに更新値を通知する。
      • ICounterReceiver インタフェースを作成して、GameControllerはリスト管理する。
      • ICounterReceiver インタフェースを持つクラスは 1 オブジェクト 1 クラスまでとする。(インスペクターのリスト表示がGameObjectで登録するため)
      • ICounterReceiver インタフェースは仮想関数として UpdateCounter 関数を持ち、継承先で実装する。
      • GameController は通知の際に、リスト保持する全てのオブジェクトの UpdateCounter 関数を呼び出す。
    • テキストラベルに持たせるクラスは ICounterReceiver インタフェースを実装する CounterTextController クラスとする。

ICounterReceiver インタフェース

  • UpdateCounter 関数定義を持つ。
  1. public interface ICounterReceiver
  2. {
  3. public void UpdateCounter(int count);
  4. }
  5.  

CounterTextController クラス

  • テキストラベル(Canvasに作成した Text(TMP))にコンポーネントとして登録する。
  1. using UnityEngine;
  2. using TMPro;
  3.  
  4. public class CounterTextController : MonoBehaviour, ICounterReceiver
  5. {
  6. TextMeshProUGUI tmp;
  7.  
  8. void Start()
  9. {
  10. tmp = gameObject.GetComponent<TextMeshProUGUI>();
  11. }
  12. public void UpdateCounter(int count) {
  13. tmp.text = count + " あおい~";
  14. }
  15. }
  16.  

GameController クラス

  • ヒエラルキーの最上位の階層に空のオブジェクトを持たせ、本クラスをコンポーネントとして持たせる。
  • 起動時に永続化オブジェクトに設定される
  • シーンを跨いで2つ目が生成された場合には新しい方は破棄するシングルトン構造。
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3.  
  4. public class GameController : MonoBehaviour
  5. {
  6. public static GameController instance;
  7.  
  8. // カウンタの通知を受けるオブジェクトのリスト(インスペクターより登録)
  9. public List<GameObject> counterReceivers;
  10. int clickCount;
  11.  
  12. void Awake() {
  13. // シーンを跨いでGameControllerがいた場合用にシングルトン実装
  14. if (instance == null) { instance = this; }
  15. else { Destroy(gameObject); }
  16. }
  17. void Start() {
  18. // オブジェクトを永続化
  19. DontDestroyOnLoad(gameObject);
  20. }
  21. public void IncrementCount() {
  22. // カウンタをインクリメントして、登録オブジェクト全てに通知
  23. clickCount++;
  24. foreach (GameObject obj in counterReceivers) {
  25. ICounterReceiver receiver = obj.GetComponent<ICounterReceiver>();
  26. if (receiver != null) {
  27. receiver.UpdateCounter(clickCount);
  28. }
  29. }
  30. }
  31. }
  32.  
  • GameControllerのインスペクターで、カウンタ値の通知先であるテキストラベルのオブジェクトをリストに登録する。

Click クラスの変更点

  • 前の記事からの増分は GameController の保持とインクリメント依頼の行のみ。
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class Click : MonoBehaviour
  6. {
  7. // 生成するprefab を簡単に差し替えできるよう public で外部から変更できるようにしておく
  8. public GameObject prefab;
  9.  
  10. // 速度は適切な速度を探れるように、publicで外部から変更できるようにしておく
  11. public float prefabSpeed = 1000;
  12. public float prefabTorque = 300;
  13. Animator anime;
  14. GameController controller;
  15.  
  16. void Start() {
  17. anime = GetComponent<Animator>();
  18. controller = GameObject.FindObjectOfType<GameController>();
  19. }
  20. void Update() {
  21. if (Input.GetMouseButtonDown(0)) {
  22. anime.SetTrigger("click_cancel");
  23. anime.SetTrigger("click");
  24.  
  25. // prefab からインスタンスを生成
  26. GameObject aoi = Instantiate(prefab, gameObject.transform.position, Quaternion.identity);
  27. Rigidbody2D aoiBody = aoi.GetComponent<Rigidbody2D>();
  28.  
  29. // 上方向のランダムな方向を決定
  30. Vector2 direction = Random.insideUnitCircle.normalized;
  31. direction.y = Mathf.Abs(direction.y);
  32.  
  33. // ランダムな回転速度を決定、整数にしたとき2で割り切れない場合は逆回転にする
  34. float torque = Random.value;
  35. if ((int)(torque*100) % 2 == 1) {
  36. torque *= -1;
  37. }
  38.  
  39. // 生み出した葵ちゃんに力を与える
  40. aoiBody.AddForce(direction * prefabSpeed, ForceMode2D.Force);
  41. aoiBody.AddTorque(torque * prefabTorque, ForceMode2D.Force);
  42.  
  43. // クリック数をインクリメントする
  44. controller.IncrementCount();
  45. }
  46. }
  47. }
  48.  

目安箱バナー