EasySave3で自作のclassを使って保存する【Unity,EasySave3】

ゲームのテンプレートを作成してる中でセーブ&ロードは必須だろうと思い実装をしていたのですが,基本EasySaveではint,sting,Vectorしか保存できないみたいなので自作のclassどうやってやるんだろうと思い,思ったよりも時間がかかったので記事にしておきます

サンプルアプリ

実際に今回は以下のようなものを作って自作のclassの情報をセーブ&ロードしてみました

  • 現在時間を取得・表示
  • 画面のクリックの取得・表示
  • 画面をクリックしたときにランダムの数字を発行・表示
  • ドラッグアンドドロップできるUIを配置(この位置を保存)

こんな感じで動きます 途中で保存,最後のほうでロードしています f:id:ayousanz:20200905014818g:plain

実装方法

難しいことではなく,単にclass -> jsonにしてからstringで保存すればよかったみたいです

Code

ドラッグアンドドロップ

using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

// Imageコンポーネントを必要とする
[RequireComponent ( typeof ( Image ) )]

// ドラッグとドロップに関するインターフェースを実装する
public class DragAndDrop : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
    [SerializeField] private Image circle;
    private Color _beforeColor;
    private Vector3 _circlePosition;

    private void Start()
    {
        _circlePosition = transform.position;
    }

    public void OnBeginDrag ( PointerEventData eventData )
    {
        _beforeColor = circle.color;
        circle.color = Color.red;
    }

    public void OnDrag ( PointerEventData eventData )
    {
        // ドラッグ中は位置を更新する
        transform.position = eventData.position;
    }

    public void OnEndDrag ( PointerEventData eventData )
    {
        circle.color = _beforeColor;
        transform.position = eventData.position;
        _circlePosition = eventData.position;
    }

    public Vector3 GetCirclePosition()
    {
        return _circlePosition;
    }

    public void SetCirclePosition(Vector3 position)
    {
        gameObject.transform.position = position;
    }
}

セーブ&ロード

using UniRx;
using UniRx.Triggers;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    [SerializeField] private ClickManager clickManager;

    [SerializeField] private DragAndDrop dragAndDrop;
    private SaveData _saveData;

    private void Start()
    {
        #region save data
        this.UpdateAsObservable().Where(_ => Input.GetKeyDown(KeyCode.S)).Subscribe(_ =>
        {
            _saveData = new SaveData();
            _saveData.Time = clickManager.GetTime();
            _saveData.RandomNumber = clickManager.GetRandomNumber();
            _saveData.ClickNumber = clickManager.GetClickCount();
            _saveData.CirclePosition = dragAndDrop.GetCirclePosition();
            SaveES3(_saveData);
        });
        #endregion

        #region load data

        this.UpdateAsObservable().Where(_ => Input.GetKeyDown(KeyCode.L)).Subscribe(_ =>
        {
            SaveData saveData = LoadES3("1");
            dragAndDrop.SetCirclePosition(saveData.CirclePosition);
            clickManager.SetText(saveData.Time,saveData.ClickNumber,saveData.RandomNumber);
        });

        #endregion
    }

    void SaveES3(SaveData saveData)
    {
        string json = JsonUtility.ToJson(saveData);
        Debug.Log(json);
        ES3.Save("1",json);
    }
    
    SaveData LoadES3(string key){
        if (ES3.KeyExists(key))
        {
            var json = ES3.Load<string>(key);
            Debug.Log(json);
            SaveData saveData = JsonUtility.FromJson<SaveData>(json);
            return saveData;
        }
        else
        {
            return null;
        }
    }
}

class SaveData
{
    public string Time;
    public string RandomNumber;
    public string ClickNumber;
    public Vector3 CirclePosition;
}

クリックしたときの処置

using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public class ClickManager : MonoBehaviour,IPointerClickHandler
{
    [SerializeField] private Text timeText;
    [SerializeField] private Text clickCountText;
    [SerializeField] private Text randomNumberText;
    private int _clickCount = 0;
    

    public void OnPointerClick(PointerEventData eventData)
    {
        int temp = Random.Range(0, 100);
        randomNumberText.text = "randomNumber:"+temp;

        _clickCount++;
        clickCountText.text = "clickCount:"+_clickCount;
        timeText.text = "now time:" + DateTime.Now.ToLongTimeString();
    }

    public string GetTime()
    {
        return timeText.text;
    }

    public string GetClickCount()
    {
        return clickCountText.text;
    }

    public string GetRandomNumber()
    {
        return randomNumberText.text;
    }

    public void SetText(string time, string clickCount, string randomNumber)
    {
        timeText.text = time;
        clickCountText.text = clickCount;
        randomNumberText.text = randomNumber;
    }
}

参考サイト

kan-kikuchi.hatenablog.com

kazupon.org

unity-shoshinsha.biz

negi-lab.blog.jp

magcat.php.xdomain.jp