シンプルなアクションゲームを作ってみようの第26回です。
今回はシーン間の遷移を作成していきます。
前回はPost Processing Stackを使ってシーンのカメラの映像にエフェクトを加えました。
シンプルなアクションゲームを作ってみようの他の記事は
シンプルなアクションゲームを作るのを通してUnityの使い方を学ぶカテゴリです。
から参照出来ます。
タイトルシーンの作成
まずはタイトルシーンを作成していきます。
Assets/Scenesフォルダで右クリックからCreate→Sceneを選択し、名前をTitleとします。
Titleシーンを開いている状態で、Assets/ScenesフォルダのStage1シーンをヒエラルキーにドラッグ&ドロップします。
ドラッグ&ドロップするとヒエラルキーでTitleシーンとStage1シーンの両方を編集することができます。
Stage1シーンのGameManagerゲームオブジェクトを選択し、Ctrl+Cキーを押してコピーしたらTitleを選択し、Ctrl+Vキーで貼り付けます。
TitleシーンのGameManager(1)ゲームオブジェクトを選択し、インスペクタで名前をGameManagerに変更し、PauseScriptは使わないので右の3つの丸を押し、Remove Componentを選択し削除します。
Stage1シーンをヒエラルキーから削除する為にStage1シーンの右の3つの丸を押し、Remove Sceneを選択し、ヒエラルキーから削除します。
これはヒエラルキー上から消えるだけで、元のAssets/SecnesフォルダのStage1シーンは消えません。
ゲーム管理データアセットの作成
ゲームで管理するデータアセットをScriptableObjectを使って作成します。
Assets/ScriptsフォルダにGameManagementDataスクリプトを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "GameManagementData", menuName = "CreateGameManagementData")] public class GameManagementData : ScriptableObject { private void Awake() { StageNum = 1; } public int StageNum { get; set; } } |
UnityのAssetsメニューにCreateGameManagementData項目を追加しています。
Awakeメソッドではスタート時に1回だけStageNumを1にして、現在のゲームステージ番号を1に初期化しています。
StageNumプロパティは現在のゲームステージ番号の取得と設定が出来ます。
Assets/Dataフォルダ内で右クリックからCreate→CreateGameManagementDataを選択しアセットファイルを作成します。
GameManagerスクリプトに処理を追加する
GameManagerスクリプトに処理を追加していきます。
まずはフィールドを追加します。
1 2 3 4 5 6 | [SerializeField] private GameManagementData gameManagementData; [SerializeField] private PlayerStatus playerStatus; |
gameManagementDataは先ほど作ったGameManagementDataアセットをインスペクタで設定します。
playerStatusは以前作ったPlayerStatusアセットをインスペクタで設定します。
次にStartメソッドの処理を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void Start() { // ゲーム関連初期化 GameOver = false; IsCountDown = true; if (SceneManager.GetActiveScene().name != "Title") { countDownText = GameObject.Find("CountDownText").GetComponent<TextMeshProUGUI>(); StartCoroutine(CountDown()); } else { // タイトルシーンの時はステージ番号を1にする gameManagementData.StageNum = 1; } } |
GameOverとIsCountDownに初期値を設定します。
SceneManager.GetActiveSceneメソッドで現在アクティブなシーンを取得し、その名前がTitleでない場合は
countDownTextの取得を行います。
そして、StartCoroutineを使ってカウントダウン表示をします。
これらはTitleシーンではないゲームシーンだけで実行します。
Titleシーンだった時はgameManagementData.StageNumを1に設定しています。
StartGameメソッドを追加します。
1 2 3 4 5 6 | public void StartGame() { playerStatus.Reset(); SceneManager.LoadScene("Stage1"); } |
playerStatusのResetメソッドを呼んでプレイヤーステータスを初期化しています。
SceneManagerのLoadSceneメソッドでStage1シーンをロードします。
スタートボタンを作成する
次にタイトルシーンにスタートボタンを作成します。
ヒエラルキーで右クリックからUI→Canvasを選択し、名前をMainCanvasとします。
MainCanvasゲームオブジェクトを選択した状態で右クリックからUI→Text – TextMeshProを選択し、名前をMainTitleとします。
MainTitleのインスペクタで設定をします。
Rect TransformのAnchor PresetsでShift+Altキーを押しながらtop stretchを選択します。
Heightは100にします。
TextMeshProのText InputにSimple Action Gameと入力します。
Vertex Colorは緑色にします。
AlignmentはCenterとMiddleにします。
これでタイトルのテキストが出来ました。
次にMainCanvasを選択した状態で右クリックからUI→Panelを選択し、名前をMainButtonPanelとします。
MainButtonPanelゲームオブジェクトを選択し、シーンビューでShiftキーを押しながら4隅にある矢印をドラッグしてゲーム画面の下の方の領域に移動します。
ゲーム画面の30%ぐらいにしました。
MainButtonPanelのインスペクタでImageの横のチェックを外し、MainButtonPanelの背景が表示されないようにします。
次にMainButtonPanelを選択した状態で右クリックからUI→Button – TextMeshProを選択し、名前をStartButtonとします。
StartButtonゲームオブジェクトの子要素のText(TMP)ゲームオブジェクトを選択し、Text InputにStartと入力します。
StartButtonを押した時に実行するメソッドを設定する
StartButtonを押した時にStage1シーンをロードするようにします。
Stage1シーンをロードするのはGameManagerスクリプトのStartGameメソッドなのでボタンを押した時に実行するようにします。
StartButtonゲームオブジェクトを選択し、インスペクタのButtonコンポーネントのOn Clickの+を押します。
次にOn ClickのところにGameManagerゲームオブジェクトをドラッグ&ドロップして設定します。
実行するメソッドにStartGameを指定します。
Build Settingsにシーンを登録する
ゲームに使用するシーンはBuild SettingsのScenes In Buildに登録しておく必要があります。
UnityエディターメニューのFile→Build Settings…を選択します。
Scenes In Buildの領域にTitleシーンとStage1シーンをドラッグ&ドロップします。
一番上のシーンがゲームで一番初めに再生されるので、Titleシーンをドラッグして一番上にします。
TitleシーンのStartボタンを押すとStage1シーンが再生されます。
ゲームクリア時やゲームオーバー時の処理も追加する
TitleシーンのStartButtonボタンを押すとStage1シーンに遷移するようになりました。
シーンの遷移が出来るようになったのでゲームクリア時やゲームオーバー時のUIを作成しシーンの移動が出来るようにします。
Stage1シーンを開きます。
ゲームクリア、ゲームオーバー時に表示するUIの作成
ゲームクリア時、ゲームオーバー時に表示するUIを作成します。
UIゲームオブジェクトを選択した状態で、右クリックからUI→Canvasを選択し、名前をGameOverとします。
GameOverゲームオブジェクトを選択した状態で、右クリックからUI→Button – TextMeshProを選択し、名前をGoToNextButtonとします。
GoToNextButtonゲームオブジェクトの子要素のText(TMP)を選択し、インスペクタで設定をします。
TextMeshProのText InputにNext Stageと入力します。
GoToNextButtonゲームオブジェクトを選択し、Ctrl+Dキーで複製し、名前をGoToTitleButtonとします。
GoToTitleButtonの子要素のText(TMP)を選択し、インスペクタのTextMeshProのText InputにGo To Titleと入力します。
GameManagerスクリプトにボタンを押した時に実行するメソッドを追加する
GoToNextButtonとGoToTitleButtonが出来たので、これらのボタンを押した時に実行するメソッドをGameManagerスクリプトに追記します。
まずはフィールドの追加です。
1 2 3 4 5 6 7 8 | // ゲームオーバー用Canvas private Canvas gameOverCanvas; // 次のシーンへ移動するボタン private GameObject goToNextButton; // タイトルシーンへ移動するボタン private GameObject goToTitleButton; |
gameOverCanvasは先ほど作ったGameOverゲームオブジェクトのCanvasコンポーネントを入れます。
goToNextButtonとgoToTitleButtonは先ほど作った該当するボタンを入れます。
次にStartメソッドに追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | void Start() { // ゲーム関連初期化 GameOver = false; IsCountDown = true; if (SceneManager.GetActiveScene().name != "Title") { gameOverCanvas = GameObject.Find("GameOver").GetComponent<Canvas>(); goToNextButton = gameOverCanvas.transform.Find("GoToNextButton").gameObject; goToTitleButton = gameOverCanvas.transform.Find("GoToTitleButton").gameObject; gameOverCanvas.enabled = false; countDownText = GameObject.Find("CountDownText").GetComponent<TextMeshProUGUI>(); StartCoroutine(CountDown()); } else { // タイトルシーンの時はステージ番号を1にする gameManagementData.StageNum = 1; } } |
gameOverCanvas、goToNextButton、gotoTitleButtonの各ゲームオブジェクトがあるのはゲームシーンだけなのでTitleシーン以外の時に取得処理を書いています。
gameOverCanvasはGameOverゲームオブジェクトを探し、そこからCanvasコンポーネントを取得します。
goToNextButtonとgoToTitleButtonはgameOverCanvasのゲームオブジェクトのTransformからGoToNextButtonとGoToTitleButtonというゲームオブジェクトを探して入れています。
gameOverCanvasは最初はチェックを外して子要素のUIを非表示にしておきたいのでgameOverCanvas.enabledにfalseを入れています。
ClearGameメソッドに処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // ゲームクリア時に実行する public void ClearGame() { GameOver = true; gameManagementData.StageNum++; if (gameManagementData.StageNum < SceneManager.sceneCountInBuildSettings) { goToTitleButton.SetActive(false); } else { goToNextButton.SetActive(false); } gameOverCanvas.enabled = true; } |
ClearGameメソッドはゲームクリア時に表示するメソッドなのでここでシーンに応じて処理を分岐します。
ゲームをクリアしたのでgameManagementData.StageNumに1を足しています。
その後のif文で現在のゲームステージ番号がSceneManager.sceneCountInBuildSettingsの値(Build SettingsのScenes In Buildに登録したシーンの数)未満である時はgoToTitleButtonを非表示にします。
これはまだ次のステージがあるのでタイトルへ移動するボタンは表示しないようにしています。
既に最後のステージまでクリアした場合はgoToNextButtonを非表示にし、タイトルシーンにしかいけないようにします。
その後gameOverCanvasのenabledプロパティにtrueを入れGameOverゲームオブジェクトのCanvasコンポーネントを有効化しています。
次にゲームをクリアできなかった時に実行するEndGameメソッドに追記します。
1 2 3 4 5 6 7 8 | // ゲームをクリア出来なかった時に実行する public void EndGame() { GameOver = true; goToNextButton.SetActive(false); gameOverCanvas.enabled = true; } |
ここではgoToNextButtonを非アクティブにした後にgameOverCanvasを有効にしています。
次にGoToNextButtonボタンとGoToTitleButtonボタンを押した時に実行したいメソッドを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 次のシーンへ移動 public void GoToNextScene() { if (gameManagementData.StageNum < SceneManager.sceneCountInBuildSettings) { SceneManager.LoadScene("Stage" + gameManagementData.StageNum); } else { SceneManager.LoadScene("Title"); } } // タイトルシーンへ移動 public void GoToTitleScene() { SceneManager.LoadScene("Title"); } |
GoToNextSceneメソッドが呼ばれた時に現在のゲームステージ番号が登録されたシーン数未満であればSceneManager.LoadSceneメソッドを使って次のシーンをロードしています。
このゲームではゲームシーンをStage1→Stage2→Stage3のように最後の文字を増やしてくような名前を付けます。
なので”Stage”に+でgameManagementData.StageNumを足してシーン名を作成しLoadSceneの引数としています。
それ以外(既に最終ステージである)であればTitleシーンに戻ります。
if文の条件処理はClearGameメソッドでgoToNextButtonを非表示にしているので、そもそも必要ないかもしれません。
1 2 3 4 5 | public void GoToNextScene() { SceneManager.LoadScene("Stage" + gameManagementData.StageNum); } |
上の処理だけでいいかも?
でもとりあえず残しておきます。
GoToTitleSceneメソッドはGoToTitleButtonを押した時にTitleシーンに移動します。
ボタンを押した時に実行するメソッドを設定する
スクリプトが出来たので、GoToNextButtonとGoToTitleButtonのインスペクタのButtonのOn ClickにGameManagerゲームオブジェクトのGameManagerスクリプトのGoToNextSceneメソッドとGoToTitleSceneメソッドを設定します。
Stage1シーンのGameManagerスクリプトにも設定する
TitleシーンのGameManagerゲームオブジェクトのGameManagerスクリプトにGameManagementDataアセットとPlayerStatusアセットを設定しましたが、Stage1シーンのGameManagerゲームオブジェクトのGameManagerスクリプトには設定していなかったのでAssets/Dataフォルダのアセットを設定をします。
ゲームステージを増やす
ここまではTitleシーンとStage1シーンしか作って登録していないので、複数のステージがある場合の検証が出来ません。
そこでAssets/ScenesフォルダのStage1シーンを選択してCtrl+Dキーで二つ複製し、名前をStage2、Stage3とし、UnityメニューのFile→Build SettingsでStage2とStage3をドラッグ&ドロップして登録します。
実行して確認してみる
機能が出来たのでTitleシーンを開いてUnityエディターのプレイボタンを押して実行してみましょう。
上のようになりました。
シーン間の移動が出来るようになりました。
終わりに
今回はシーン間の移動機能を作成しました。
次回はゲーム内に霧を発生させてみます。