Sample data persistence

Below is a behavior script I designed for handling data persistence in a simple manner. This could be greatly expanded and customized, but will work for simple game saving needs out of the box.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Xml;
using System.IO;


public class DataManager : MonoBehaviour
{
    private bool _IsLoaded;
    private bool _IsNew;
    
    private DataSet _DS;
    private DataTable _TblSimpleProperty;
    private DataColumn _ColSimplePropertyKey;
    
    private string _XmlPath = Application.dataPath + @"/DataManager.xml";
    private string _DSName = @"DataManagerData";
    private string _TableName = @"SimpleProperty";

    private string _KeyColName = @"Key";
    private string _BoolValueColName = @"BoolValue";
    private string _IntValueColName = @"IntValue";
    private string _FloatValueColName = @"FloatValue";
    private string _StringValueColName = @"StringValue";

    public bool IsLoaded
    {
        get { return _IsLoaded; }
    }

    public bool IsNew
    {
        get { return _IsNew; }
    }

    public DataSet DS 
    {
        get{ return _DS; }
    }

    void Awake()
    {
        DontDestroyOnLoad(this);
        _IsLoaded = false;
        _IsNew = false;
        _DS = new DataSet(_DSName);
    }

    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (!_IsLoaded)
        {
            // make sure data has been loaded by this time
            Load();
        }
    }

    void OnApplicationQuit()
    {
        if (_IsLoaded  ( _DS.HasChanges() || _IsNew))
        {
            Save();
            _DS.AcceptChanges();
            Debug.Log("DataManager: Data Saved!");
        }
    }

    private DataRow FindPropertyRow(string key)
    {
        DataRow retRow = null;
        int propRowIdx = _TblSimpleProperty.DefaultView.Find(new object[] { key });
        if (propRowIdx >= 0)
        {
            DataRowView propRow = _TblSimpleProperty.DefaultView[propRowIdx];
            retRow = propRow.Row;
        }
        return retRow;
    }

    public bool Exists(string key)
    {
        return (FindPropertyRow(key) != null);
    }

    public SimpleProperty GetSimpleProperty(string key)
    {
        SimpleProperty retProp = null;
        DataRow propRow = FindPropertyRow(key);
        if(propRow != null)
        {
            
            retProp = new SimpleProperty(key);
            retProp.BoolValue = (bool)propRow[_BoolValueColName];
            retProp.IntValue = (int)propRow[_IntValueColName];
            retProp.FloatValue = (float)propRow[_FloatValueColName];
            retProp.StringValue = (string)propRow[_StringValueColName];
        }
        return retProp;
    }

    public List<SimpleProperty> GetSimpleProperties(List<string> keyList)
    {
        List<SimpleProperty> propList = new List<SimpleProperty>();
        foreach (string key in keyList)
        {
            propList.Add(GetSimpleProperty(key));
        }
        return propList;
    }

    public void SetSimpleProperty(SimpleProperty prop)
    {
        DataRow propRow = FindPropertyRow(prop.Key);
        if (propRow == null)
        {
            // not in the table so create a new row and add it
            propRow = _TblSimpleProperty.NewRow();
            propRow[_KeyColName] = prop.Key;
            _TblSimpleProperty.Rows.Add(propRow);
        }
        // update the column values
        propRow[_BoolValueColName] = prop.BoolValue;
        propRow[_IntValueColName] = prop.IntValue;
        propRow[_FloatValueColName] = prop.FloatValue;
        propRow[_StringValueColName] = prop.StringValue;
    }

    public void DeleteSimpleProperty(string key)
    {
        DataRow propRow = FindPropertyRow(key);
        propRow.Delete();
    }

    public SimpleProperty SetPropertyValue(string key, bool boolValue)
    {
        SimpleProperty prop = GetSimpleProperty(key);
        prop.BoolValue = boolValue;
        SetSimpleProperty(prop);
        return prop;
    }

    public SimpleProperty SetPropertyValue(string key, int intValue)
    {
        SimpleProperty prop = GetSimpleProperty(key);
        prop.IntValue = intValue;
        SetSimpleProperty(prop);
        return prop;
    }

    public SimpleProperty SetPropertyValue(string key, float floatValue)
    {
        SimpleProperty prop = GetSimpleProperty(key);
        prop.FloatValue = floatValue;
        SetSimpleProperty(prop);
        return prop;
    }


    public SimpleProperty SetPropertyValue(string key, string stringValue)
    {
        SimpleProperty prop = GetSimpleProperty(key);
        prop.StringValue = stringValue;
        SetSimpleProperty(prop);
        return prop;
    }


    public void Load()
    {
        FileInfo xmlFile = null;
        StreamReader reader = null;

        xmlFile = new FileInfo(_XmlPath);
        if (xmlFile != null  xmlFile.Exists)
        {
            // load the dataset if the file is there
            _IsNew = false;
            reader = xmlFile.OpenText();
            _DS.ReadXml(reader,XmlReadMode.ReadSchema);
            _TblSimpleProperty = _DS.Tables[_TableName];
            _ColSimplePropertyKey = _TblSimpleProperty.Columns[_KeyColName];
            _TblSimpleProperty.DefaultView.Sort = _KeyColName;
            _DS.AcceptChanges();
            Debug.Log("DataManager: Data Loaded!");
        }
        else
        {
            _IsNew = true;
            Debug.Log("DataManager: " + _XmlPath + " does not exist, initializing data.");
            InitializeSchema();
        }
        _IsLoaded = true;
    }

    public void Save()
    {     
        _DS.WriteXml(_XmlPath, XmlWriteMode.WriteSchema);           
    }

    void InitializeSchema()
    {
        //Create the default data table for storing our simple properties
        _TblSimpleProperty = new DataTable(_TableName);
        
        _ColSimplePropertyKey = new DataColumn(_KeyColName, typeof(string));
        _ColSimplePropertyKey.AllowDBNull = false;
        _TblSimpleProperty.Columns.Add(_ColSimplePropertyKey);
        _TblSimpleProperty.PrimaryKey = new DataColumn[] { _ColSimplePropertyKey };

        _TblSimpleProperty.Columns.Add(new DataColumn(_BoolValueColName, typeof(bool)));
        _TblSimpleProperty.Columns.Add(new DataColumn(_IntValueColName, typeof(int)));
        _TblSimpleProperty.Columns.Add(new DataColumn(_FloatValueColName, typeof(float)));
        _TblSimpleProperty.Columns.Add(new DataColumn(_StringValueColName, typeof(string)));

        _TblSimpleProperty.DefaultView.Sort = _KeyColName;

        _DS.Tables.Add(_TblSimpleProperty);
        Debug.Log("DataManager: Schema Initialized.");
    }

    // This embedded class is the object for the simple property objects
    // stored in the SimpleProperty data table.
    public class SimpleProperty
    {
        public string Key;
        public bool BoolValue;
        public int IntValue;
        public float FloatValue;
        public string StringValue;

        public SimpleProperty(string key)
        {
            Key = key;
            BoolValue = false;
            IntValue = 0;
            FloatValue = 0f;
            StringValue = null;
        }

        public SimpleProperty(string key, bool boolValue, int intValue, float floatValue, string stringValue) : this(key)
        {            
            BoolValue = boolValue;
            IntValue = intValue;
            FloatValue = floatValue;
            StringValue = stringValue;
        }

        public SimpleProperty(string key, bool boolValue)
            : this(key)
        {
            BoolValue = boolValue;
        }

        public SimpleProperty(string key, int intValue)
            : this(key)
        {
            IntValue = intValue;
        }

        public SimpleProperty(string key, float floatValue)
            : this(key)
        {
            FloatValue = floatValue;
        }

        public SimpleProperty(string key, string stringValue)
            : this(key)
        {
            StringValue = stringValue;
        }

    }
}

264580–9520–$datamanager_109.cs (8.05 KB)

Welcome to the forums, nice first post! Code sharing right out of the gate, I like it. :slight_smile:

Suggestion: use the Code button or manually wrap code in a [ code ]…[ /code ] block (no spaces) for better code formatting. I’m going to edit your post and add those so you can see what I mean. :slight_smile:

Thanks for the welcome. I will make sure to use the code tags in the future.

I get the following error:

Assets/datamanager_109.cs(4,14): error CS0234: The type or namespace name Data' does not exist in the namespace System’. Are you missing an assembly reference?

You have to copy the dll’s from the unity installation into your assets folder.

Which dlls specifically? I copied the dlls from Program Files->Unity->Editor into the project and am still getting the same error.

Nevermind. I answer this myself. the code must be in the same folder as the dll’s. Doh!