今回はニフクラ mobile backend のサンプルプロジェクト「シューティングゲームにランキングとゴースト機能を追加」のシーン Stage を改造します。
使用されているスクリプトベースのレガシーUI を通常のUIオブジェクトに置き換える作業を中心にいくつか変更してみました。
ニフクラ mobile backend は富士通クラウドテクノロジーズ株式会社が提供するスマートフォンアプリでよく利用される汎用的な機能をクラウドから提供するサービス。
ニフクラ mobile backend の公式サイトにはサービスの使用方法のドキュメントやサンプル、チュートリアルが用意されています。
Unity サンプル&チュートリアル一覧 ニフクラ mobile backend
サンプルプロジェクトはこちらからダウンロードできます。 GitHub – NIFCloud-mbaas_NCMB2dst_comp
サンプルプロジェクトのシーン Stage を開いて [Hierarchy]ウィンドウ > Main Camera を選択。 [Inspector]ウィンドウで GUI Layer 削除します。
ゲームタイトルのオブジェクトはレガシーUIオブジェクトを使用しているので通常のUIオブジェクトに置き換えます。
テキストオブジェクトと同時に作成されたオブジェクト Canvas はCanvas Scaler (Script) コンポーネントの設定を変更しておきます。
サンプルプロジェクトでは[Leader Board]ボタンと[Ghost]ボタンがスクリプトベースのボタンで実装されていますが、これを通常のUIオブジェクトに置き換えます。それに加えてマウス左クリック(画面タップ)でゲームスタートの処理をUIボタンクリックでスタートに変更します。
オブジェクト Button StartWithGhost の[Text]コンポーネントはリッチテキストのタグを使用してのフォントサイズを調整。
変更したボタンは[Scene]ビューでこのようになっています。
シーン Stage を再生するとエラーが発生します。
これはスクリプト Manager のなかでタイトルオブジェクトの有効/無効でゲームプレイ中の判定処理を行っており、削除したオブジェクト Title を参照できないためです。
スクリプトの主な改造点はつぎの部分になります。
コードはこのようになっています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// シーン処理のクラスを使用する宣言
using UnityEngine.SceneManagement;
public class Manager : MonoBehaviour
{
// プレイヤーオブジェクトを格納する変数
public GameObject player;
// プレイヤーゴーストオブジェクト を格納する変数
public GameObject ghost;
// タイトルテキストオブジェクトを格納する変数
public GameObject textTitle;
// ゲームを開始するボタンオブジェクトを格納する変数
public GameObject buttonStart;
// プレイヤーゴースト有りでゲームを開始するボタンオブジェクトを格納する変数
public GameObject buttonStartWithGhost;
// リーダーボードを表示するボタンオブジェクトを格納する変数
public GameObject buttonLeaderBoard;
// BGMオブジェクトを格納する変数
public GameObject bgm;
// BGMオブジェクトの DontDestroy フラグ
private static bool dontDestroy = false;
//ゲーム起動時の処理
void Awake()
{
// BGMオブジェクトが DontDestroy でない場合
if (!dontDestroy)
{
// BGMオブジェクトを DontDestroy に設定してシーンが切り替わっても削除しない
DontDestroyOnLoad(bgm);
// DontDestroy フラグ を true にする
dontDestroy = true;
}
// BGMオブジェクトが DontDestroy の場合
else
{
// BGMオブジェクトが DontDestroy の場合シーンから削除
Destroy(bgm);
}
//ゴーストボタンを非表示にする
buttonStartWithGhost.SetActive(false);
}
// ゲーム実行中の繰り返し処理
void Update()
{
// ゲームプレイ中でなければ(IsPlaying()の返り値が false の場合)
if (!IsPlaying())
{
// Bg_ghost.csでゴーストデータを取得できたら、ゴーストボタンを表示する
if (Bg_ghost.readyGhost == true)
{
// ボタンオブジェクト buttonGhost を有効にする
buttonStartWithGhost.SetActive(true);
}
}
}
// UIボタンクリック時の処理
public void OnClick(string buttonName)
{
// ボタンクリックの引数が Start であれば
if (buttonName == "Start")
{
// ゲームスタート(プレイヤーゴースト無し)
//(GameStart 処理を引数 false で実行)
GameStart(false);
}
// ボタンクリックの引数が Ghost であれば
if (buttonName == "StartWithGhost")
{
// プレイヤーゴースト有りでゲームプレイを開始
//(GameStart 処理を引数 true で実行)
GameStart(true);
}
// ボタンクリックの引数が LeaderBoard であれば
if (buttonName == "LeaderBoard")
{
// シーン LeaderBoard のロード
SceneManager.LoadScene("LeaderBoard");
}
}
// ゲームプレイ開始の処理(引数でプレイヤーゴーストの有効無効を判定)
void GameStart(bool withGhost)
{
// タイトルテキストを非表示にする
textTitle.SetActive(false);
// ゲームを開始するボタンオブジェクトを非表示
buttonStart.SetActive(false);
// プレイヤーゴースト有りでゲームを開始するボタンオブジェクトを非表示
buttonStartWithGhost.SetActive(false);
// リーダーボードボタンオブジェクトを非表示
buttonLeaderBoard.SetActive(false);
// 変数 withGhost が true の場合
if (withGhost == true)
{
// プレイヤーゴーストを表示する
Instantiate(ghost, ghost.transform.position, ghost.transform.rotation);
// プレイヤーの発生処理
Instantiate(player, player.transform.position, player.transform.rotation);
}
// 変数 withGhost が false の場合(プレイヤーゴーストが無効の場合)
else
{
// プレイヤーの発生処理
Instantiate(player, player.transform.position, player.transform.rotation);
}
}
// ゲームオーバー時の処理 (プレハブ player から呼び出す)
public void GameOver()
{
// スクリプト Score の 関数 Save () を実行
FindObjectOfType().Save();
//シーン SaveScore をロードする
SceneManager.LoadScene("SaveScore");
}
// ゲームプレイ中かどうか判定処理
public bool IsPlaying()
{
// タイトルテキストが非表示( false )であれば true を返す
return textTitle.activeSelf == false;
}
}
[Inspector]ウィンドウ > Manager (Script)コンポーネントのフィールドに必要なオブジェクトを割り当てます。まだUIボタンに処理割り当ててないのでゲームはスタートできませんが、再生してエラーが出なければひとまずOKです。
シーンに配置したUIオブジェクト Button Start 、Button StartWithGhost、Button LeaderBoard をクリックしたときの処理を[Inspector]ウィンドウで設定します。
スクリプト Manager の関数 public void OnClick(string buttonName) をボタンクリック時の処理に割り当て、関数内の処理を引数 buttonName で指定します。
オブジェクは Manager を指定、関数は Manager > OnClick() を指定、引数フィールドに Start を入力。
オブジェクは Manager を指定、関数は Manager > OnClick() を指定、引数フィールドに StartWithGhost を入力。
オブジェクは Manager を指定、関数は Manager > OnClick() を指定、引数フィールドに LeaderBoard を入力。
これでひとまずゲームをスタートできるようになりました。[START with Ghost]ボタン、[LeaderBoard]ボタンをクリックしてシーンが切り替わればOKです。
シーン Srage のスクリプト Manager でBGM オブジェクトをシーンが切り替わっても削除しない処理をしたので、他のシーンからBGMオブジェクト削除します。
レガシーUIオブジェクトのスコア表示を通常のUIオブジェクトに変更します。
[Hierarchy]ウィンドウ > Score GUI の階層をすべて選択。レガシーUIのオブジェクトは不要なのですべて削除します。シーン Stage にUIオブジェクトを配置してスコア表示を行います。
[Hierarchy]ウィンドウ > [Create]ボタン > UI > Text を選択。名前を Text Score に変更。
Text (Script)コンポーネントの設定はこのようにしました。文字整列の Paragraph > Alignment は右上寄せにしました。
スクリプト Score を修正します。不要になったレガシーUIのスコア表示処理の部分をUIオブジェクトを使用した処理の置き換えます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UI処理のクラスを使用する宣言
using UnityEngine.UI;
public class Score : MonoBehaviour
{
// スコアテキストコンポーネントを格納する変数
public Text textScore;
// スコアを格納する変数
private int score;
// ローカルデータ PlayerPrefs でスコアを保存するためのキーを作成
private string ScoreKey = "Score";
// ゲーム開始時の処理
void Start()
{
// ゲーム開始前の状態に戻す(スコアを0に戻す)
Initialize();
}
// ゲーム実行中の繰り返し処理
void Update()
{
// スコアの更新
// 変数 score の値を文字列として text 要素に格納
textScore.text = "SCORE " + score.ToString();
}
// ゲーム開始前の状態に戻す
private void Initialize()
{
// スコアを0に戻す
score = 0;
}
// 敵を破壊してスコアを加算する処理
public void AddPoint(int point)
{
// 変数 score に point を加算して格納
score = score + point;
}
// スコアの保存処理(スクリプト Manager で呼び出す )
public void Save()
{
// ローカルデータにキー ScoreKey の値 score をセット
PlayerPrefs.SetInt(ScoreKey, score);
// ローカルデータデータを保存する
PlayerPrefs.Save();
// ゲーム開始前の状態に戻す(スコアを0に戻す)
Initialize();
}
}
修正したスクリプト Score は Canvas に割り当て。[Inspector]ウィンドウ > Score (Score) コンポーネント > Text Score フィールドには Text Score を割り当てます。
今回の内容をWebGLでビルドしてみました。サウンドはミュートしています。
画像クリックで再生(ファイルサイズ:約7MB)