【unity】放置ゲーム/ソシャゲ系のオフライン報酬1【スクリプト】

【unity】放置ゲーム/ソシャゲ系のオフライン報酬1【スクリプト】

2020年10月25日
Unity

記述日 2020/10/25
unity 2019.3.2

※追記:第2回はこちら

放置ゲーム系のオフライン報酬1

放置ゲーム(ソシャゲ)系では、アプリを起動していない時でも報酬を獲得したり、スタミナが回復するなどがあります。

そこらへんの処理を書いてみたくなったのでメモ。

アプリを辞めた時に呼ばれる OnApplicationQuit で時間を保存して、再開時に読み込み&時間の計算をしています。

ソースコードにコメントを書いているので基本的にはそちらを見て下さい。

※サーバー時間は使っていません。

ローカルのみで処理を行っているのでスマホの時計をずらす事で不正できてしまいます。

 

プロジェクト

■Githubプロジェクト ※他の実験のソースコード等混ざってます

git_gamebox_public

GitHub - gamebox777/git_gamebox_public

Contribute to gamebox777/git_gamebox_pub…
github.com

 

■シーン/ソースコードなど

gamebox_experiment\Assets\OfflineTimeMnager\OfflineTimeMnager01

・OfflineTimeMnager01.unity

・OfflineTimeMnager01.cs

・PlayerPrefsJsonUtil.cs

 

■確認方法

OfflineTimeMnager01.unityシーンを開いて、unityエディタの再生/停止などを行うと、
コンソールにログが出力されます。

※永続データを削除する際は
unityメニュー Edit > Clear All PlayerPrefs で消す事で初期化できます。参考サイト

ソースコード

ソースはこちら。

↓ リンクを押すとgithubで見る(おすすめ)

OfflineTimeMnager01.cs

 

 

備考/ポイントなど

DateTime型はPlayerPrefs/Jsonでシリアライズ出来ないので文字列型で保存して、戻しています。
↑ 最初そのまま保存しようとしてできなくて、少しはまった。

・OnApplicationPauseやOnApplicationFocus時の処理も必要だと思いますがこの記事ではやっていません。(やらないと駄目っぽい)

・永続データはJSONシリアライズしていますが、今は変数ひとつなのでPlayerPrefsのstring型でセーブする様に変更したほうがシンプルになります。

続き:放置ゲーム/ソシャゲ系のオフライン報酬2

【unity】放置ゲーム/ソシャゲ系のオフライン報酬2【スクリプト】

記述日 2020/11/01 unity 2019.3.2 放置ゲーム系のオフラ…
www.unitygamebox.com

 

unity他のプロジェクトあり一覧

 

検索用

ソシャゲ 放置 unity スクリプト script Idle

using System;
using UnityEngine;

/// <summary>
/// オフライン時の経過時間テスト
/// 2020/10/25:ver1.0
/// todo:OnApplicationPause,OnApplicationFocus時の処理は行っていません
/// </summary>
public class OfflineTimeMnager01 : MonoBehaviour
{
    /// <summary> PlayerPrefsのセーブキー </summary>
    const string SaveKeyString = "OfflineTimeMnager01SaveKey";
    
    /// <summary> 使用するクラス </summary>
    [HideInInspector]
    public ClassSaveData classSaveData;

    /// <summary> 前回辞めた時間(セーブしていた時間) </summary>
    [HideInInspector]
    public DateTime oldDateTime;
    
    private void Awake()
    {
        SaveDataLoad();    //セーブデータをロードする
    }

    // Start is called before the first frame update
    void Start()
    {
        CalculateOfflineEarnings();    // オフライン時の経過時間を計算
    }
    
    /// <summary>
    /// オフライン時の経過時間を計算
    /// </summary>
    public void CalculateOfflineEarnings()
    {
        DateTime currentDateTime = DateTime.Now;
        if (oldDateTime > currentDateTime) {
            //データ不正:セーブデータの時間の方が今の時間よりも進んでいたので今の時間を入れる
            oldDateTime = DateTime.Now;
        }
        
        //アプリを停止→再開していた経過時間計算
        TimeSpan timeElasped = currentDateTime - oldDateTime;    //経過した時間
        float elapsedTimeInSeconds = (int)Math.Round(timeElasped.TotalSeconds, 0, MidpointRounding.ToEven); //経過時間を
        Debug.Log($"オフラインでの経過時間:{elapsedTimeInSeconds}秒");
    }
    
    /// <summary>
    /// アプリケーションが終了された時に呼ばれる
    /// </summary>
    private void OnApplicationQuit()
    {
        Debug.Log("アプリが中断されたのでセーブ");
        SaveDataSave();
    }

    /// <summary>
    /// セーブデータ:ロード
    /// </summary>
    public void SaveDataLoad()
    {
        //セーブデータ存在チェック
        if (PlayerPrefsJsonUtil.ExistData(SaveKeyString)) {
            //セーブデータ有り
            classSaveData = PlayerPrefsJsonUtil.GetObject<ClassSaveData>( SaveKeyString );
            oldDateTime = classSaveData.GetDateTime();
            string str = oldDateTime.ToString("yyyy/MM/dd HH:mm:ss");
            Debug.Log($"アプリ開始時:セーブされていた時間:{str}");
            
            str = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            Debug.Log($"今の時間:{str}");
        }
        else {
            //セーブデータ無し
            Debug.Log("セーブデータがないのでセーブデータ作成");
            classSaveData = CreateSaveData();
            oldDateTime = DateTime.Now;
        }
    }

    /// <summary>
    /// セーブデータ:セーブ
    /// </summary>
    public void SaveDataSave()
    {
        //デバッグ表示
        string str = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        Debug.Log($"アプリ終了時:セーブ時の時間:{str}");

        //DateTime型をString型に変換してJSONで保存
        classSaveData.dateTimeString = DateTime.Now.ToBinary().ToString();
        PlayerPrefsJsonUtil.SetObject<ClassSaveData>(SaveKeyString,classSaveData,true);
    }
    
    /// <summary>
    /// セーブデータ作成
    /// </summary>
    /// <returns></returns>
    public ClassSaveData CreateSaveData()
    {
        ClassSaveData saveData = new ClassSaveData
        {
            dateTimeString = DateTime.Now.ToBinary().ToString(),
        };
        return saveData;
    }
    
    /// <summary>
    /// セーブデータクラス
    /// </summary>
    [Serializable]
    public struct ClassSaveData
    {
        /// <summary> DateTime型はシリアライズ出来ないので文字列型 </summary>
        public string dateTimeString;

        /// <summary>
        /// DateTimeを文字列型で保存しているので、DateTime型に戻して取得
        /// </summary>
        /// <returns></returns>
        public DateTime GetDateTime()
        {
            DateTime datetime = System.DateTime.FromBinary (System.Convert.ToInt64 (dateTimeString));
            return datetime;
        }
    }
    
}