まるとこ学習帳

Unityでゲームを作っています。学んだことの記録を書きます。

【RPG風バトル】シーン間でデータを渡してみた【Unity】(後編)

前回の記事の続きになります。
marutoko.hatenablog.com

参考にした記事はこちら。
note.com

!注意!
前回の記事にも書きましたが、この方法で「確実に安全」にデータを渡せているか
自信がないので、参考にされる際は各自検証の上やってみてくださいm(_ _)m

今回のテーマ

さて、前回は戦闘シーンでHPが減った状態から、ダンジョンシーンに残りHPを
引き継ぐということをやってみました。
それだけだと、ダンジョンシーンから戦闘シーンに残りHPが引き継がれない、
つまり再び戦闘シーンに入ったときにHPが初期化(全回復)されてしまう!
ということになるので、今回は

「ダンジョンシーンの残りHPを戦闘シーンに引き継ぐ」というのを
やってみようと思います。
やることは前回と似たような作業になります。

BattleController.cs を編集

BattleSceneのBattleController.cs をちょこっと編集します。
今回は、前回の逆でDungeonSceneからBattleSceneへ残りHPを渡す、
つまりGameManagerScript内のPhpremの値をBattleController内のPhpに渡す
ことになるので、private int にしていたPhpを、外からアクセスできるように
public int へと書き換えます。

BattleController.cs書き換え

冒頭部分

public int Php = 100; //プレイヤーHP 他シーンから値を受け取るためpublicにする

これでPhpに外からアクセスできるようになりました。

BattleControllerオブジェクトにタグを追加

前回同様、他スクリプトからGameObject.FindWithTag を使って
BattleControllerオブジェクトを見つけることになるので、
タグを追加しておきます。
BattleController のインスペクターから新しく「BattleController」タグを
作って追加します。
タグの追加方法は前回記事に書きましたのでご参照ください。

タグを追加したら、DungeonSceneのGameManagerScript.cs を編集して、
シーン切り替え時にPhpremの値をPhpに渡す処理を書きます。

GameManagerScript.cs を編集

ここから追記 〜 追記ここまで の部分を追記します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;

public class GameManagerScript : MonoBehaviour
{
    public int Phprem = 100; //プレイヤーの残りHP

    private void Start()
    {
        Debug.Log("ダンジョンシーンに切り替わった");
        Debug.Log("プレイヤーの残りHP " + Phprem);
    }

// ここから追記
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))
        {
            // イベントにメソッドを登録
            SceneManager.sceneLoaded += GameSceneLoaded2;
            // バトルシーンに切り替え
            SceneManager.LoadScene("BattleScene");

            void GameSceneLoaded2(Scene next, LoadSceneMode mode)
            {
                // シーン切り替え後のスクリプトを取得
                var battleController = GameObject.FindWithTag("BattleController").GetComponent<BattleController>();

                // データを渡す処理
                battleController.Php = Phprem; //次のシーンにプレイヤーの残りHPを渡す

                // イベントからメソッドを削除
                SceneManager.sceneLoaded -= GameSceneLoaded2;
            }
        }
    }
// 追記ここまで

}

Update関数を追加して、Returnが押されたら残りHPを引き渡して戦闘シーンに
切り替わるようにします。

やっていることは前回と同様です。
GameSceneLoaded2メソッドをシーン切り替え時に呼ばれるメソッドとして追加し、
GameSceneLoaded2メソッド内でBattleControllerスクリプトを見つけて
その中のPhpにPhpremの値を渡します。
最後にイベントからメソッドを削除しておきます。

再生してみる

シーンを再生してみます!
BattleSceneを開き、再生します。
BattleSceneからDungeonSceneへのHPの引き渡しは前回できたので、
確認するべきなのはBattleScene → DungeonScene → BattleScene に遷移
したとき、ダンジョンシーンから戦闘シーンへHPが引き継がれているかどうかです。

具体的には2回目の戦闘シーンに入ったときに、「プレイヤーHP40」と出れば
うまくいっていることになります。
どうでしょうか?

シーンを再生してみました。

BattleScene → DungeonScene → BattleScene と遷移した結果の
最初のBattleSceneの途中から表示されています。

はじめの戦闘シーンで残りHPが40になり、
遷移後のダンジョンシーンで残りHPが40と引き継がれていて、
その後「バトルスタート」で二回目の戦闘シーンに切り替わり、
ちゃんとプレイヤーHPが40になっています。

うまくいきました!

おまけ

ゲーム画面でもHPが表示されるようにしてみました。
方法については今までの応用でできるので割愛させていただきます。

工夫した点としては、敵を倒した時敵のHP表示がマイナスになってしまうので、
Ehp<=0のときは0と表示されるようにif文を使って書き直しました。
(もっとスマートな方法あるかも)

他は、バトル終了時、クリア画像が出るアニメーションが終わる前に
次のシーンへ遷移してしまっていたので、
DOTweenの.OnCompleteを使ってアニメーション終了後に
シーンを遷移させるように変更しました。

実行したゲーム画面

↓ ダンジョンシーン。(思いっきり草原ですが)初期HPは100。

↓ モンスターにエンカウントしてバトルスタート!

↓ バトルに勝利!残りHPは40。

↓ ダンジョン(草原)シーンにもどる。残りHPが引き継がれています。

↓ 再びモンスターに遭遇!ちゃんと残りHPが40になっています。

心配な点

Unityの実行画面ではうまくいきましたが、不安もあります。
参考記事では「シーンA → B にデータをセットする」ことで
安全にデータを渡していましたが、今回は
BattleScene → DungeonScene → BattleScene と2シーン間で
データを渡し合っています。
もしかしたらこの点で何か不具合が出てくるかもしれません。
参考にされる際は吟味してやってみてください。

それではまた〜!