【Unity備忘録10】オフライン報酬を実装するために、前回セーブからの経過時間を取得する(サーバー利用無し)

アイキャッチ ゲーム制作
スポンサーリンク

こんにちは、slashです。
今回は放置ゲームでよくあるオフライン報酬を実装するため、
前回のセーブからの経過時間を取得する方法のメモです。

この方法で
プレイヤーがゲームを起動していない時間も
自動的に何か稼いでくれる機能を実装できます。

注意

今回はPCの時刻を取得して経過時間を取得する方法のため、
プレイヤーがPCの時刻を操作すると不正に報酬を獲得できてしまいます。
この点はご了承ください。

DateTime型、TimeSpan型の変数について

今回はDateTime型、TimeSpan型の変数を使って
時刻や時間の長さの処理を行います。

DateTime型は時刻の情報を格納する変数、
TimeSpan型は時間の長さを格納する変数です。
これらの型の変数を使用するには
スクリプト冒頭にusing Systemの行を追加する必要があります。

スクリプトを作成

新規でC#Scriptを作成します。
ファイル名はここでは「OfflineRewardManager」と
名付けておきます。

そして、C#Scriptを以下のように編集します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//この行を追加

public class OfflineRewardManager : MonoBehaviour
{
    DateTime SaveTime;//セーブ時の時刻
    string SaveTimeStr;//セーブ時の時刻を文字列化したもの

    DateTime NewDate;//再開時の時刻
    DateTime OldDate;//前回セーブ時の時刻
    string OldDateStr;//前回セーブ時の時刻(文字列)
    TimeSpan PlayerAwayTime;//前回セーブからゲーム再開までの時間の長さ
    int PlayerAwaySeconds;//前回セーブからゲーム再開までの時間の長さを秒単位に直したもの

    // Start is called before the first frame update
    void Start()
    {
        //ゲーム開始時にセーブデータを読み込む
        DataLoad();
    }

    //データをセーブするためのメソッド
    public void DataSave()
    {
        SaveTime = DateTime.UtcNow;//セーブ時の時刻を取得
        SaveTimeStr = SaveTime.ToString();//セーブ時の時刻を文字列にして格納
        PlayerPrefs.SetString("Date", SaveTimeStr);//SaveTimeStrの内容をセーブ
    }

    //データを読み込んで前回セーブからの経過時間を計算するメソッド
    void DataLoad()
    {
        NewDate = DateTime.UtcNow;//ゲーム再開時の時刻を取得
        OldDateStr = PlayerPrefs.GetString("Date", "");//前回セーブ時の時刻(文字列)を取得

        if (DateTime.TryParse(OldDateStr, out OldDate))
        {
            //OldDateStrをDateTime型変数に変換成功
            PlayerAwayTime = NewDate - OldDate;//再開時と前回セーブ時の時刻の差分を取得
            PlayerAwaySeconds = (int)PlayerAwayTime.TotalSeconds;//オフライン時間を秒で取得
            Debug.Log("前回のセーブからの経過時間:" + PlayerAwaySeconds + "秒");//
        }
        else
        {
            PlayerAwaySeconds = 0;
            Debug.Log("変換失敗");
        }

    }
}
スポンサーリンク

オブジェクトの配置

オブジェクトの配置をやっていきます。

スクリプトをアタッチするための空オブジェクトを作成

ヒエラルキービューを右クリックして
CreateEmptyから空オブジェクトを作成します。
このオブジェクトは「OfflineReward」という名前にしておきます。

そして、新しくできた空オブジェクトに
先ほど作成したOfflineRewardManagerをアタッチします。

図1 空オブジェクトを作成してScriptをアタッチ

データセーブ用のボタンの作成

ヒエラルキービューを右クリックして
UI > Button – TextMeshProからボタンを設置します。

図2 ボタンを作成

そして、ボタンのインスペクタービューから
On Click()の「+」マークをクリック

「OfflineReward」オブジェクトを
ドラッグアンドドロップでセット

OfflineRewardManager.DataSave()を選択

図3 ボタンの設定を行う

これでボタンがクリックされた時に
DataSave()が実行されて時刻がセーブされます。

参考記事

ゲームを実行する

ゲームを実行して動作を確認します。

初回起動時

初回の実行時はコンソールに「変換失敗」と表示されるかと思います。

図4 初回起動時は変換失敗する

DataLoad()メソッドにある条件分岐
if (DateTime.TryParse(OldDateStr, out OldDate))は
TryParseを使用して、OldDateStr(String型)がDateTime型に
変換可能かどうか判定しています。

引数1つ目の「OldDateStr」が
DateTime型に変換可能であればtrue、
そうでなければfalseとなります。
OldDateStrは前回セーブ時の時刻が
文字列として代入されるようにしてありますが、
初回プレイ時はセーブデータがありませんので、
DateTime型への変換ができず、falseとなります。

そのため、Debug.Log(“変換失敗”);が実行されて
コンソールに「変換失敗」と表示されます。

では、画面内にあるボタンをクリックしてみましょう。
DataSave()メソッドが実行されて、
その時点での時刻がセーブされます。

ボタンをクリックしたら一旦ゲームを終了します。

2回目の起動

少し時間を空けてゲームを再度起動します。

すると、次はコンソールに
前回のセーブからの経過時間:○秒」のように
表示されるかと思います。

図5 セーブデータがある状態で起動

今回はセーブデータがある状態での起動となるので
if (DateTime.TryParse(OldDateStr, out OldDate))の分岐はtrueとなり
前回セーブ時の時刻と、今回起動時の時刻の差分が計算される事になります。

最後に

このように
前回のセーブからの経過時間が取得できれば
経過時間に時間あたりの報酬を掛け算して
オフライン報酬が計算できますね。

コメント

タイトルとURLをコピーしました