Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Location of Application.persistentDataPath in a build

Tags:

json

c#

unity3d

When I run my game from the editor and save load data, I find that data in: C:\Users\User\AppData\LocalLow\DefaultCompany\projectname\data.

When I build it and get an executable, that data still loads fine, but if I save and restart, it does not get saved. However it does when I launch it from the Editor.

Is this a fault in my code or is the files somewhere else when I don't run it from Unity Editor?

Later when I export the game to launch it, I have persistent data I Json files that have to come with it for the game to work.

For clarity, here is the class that handles save/load of Json:

public class DataHandler
{
    //Save Data
    public static void saveData<T>(T dataToSave, string dataFileName)
    {
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Convert To Json then to bytes
        string jsonData = JsonUtility.ToJson(dataToSave, true);
        byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);

        //Create Directory if it does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
        }
        //Debug.Log(path);

        try
        {
            File.WriteAllBytes(tempPath, jsonByte);
            Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
            Debug.LogWarning("Error: " + e.Message);
        }
    }

    //Load Data
    public static T loadData<T>(string dataFileName)
    {
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Exit if Directory or File does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Debug.LogWarning("Directory does not exist");
            return default(T);
        }

        if (!File.Exists(tempPath))
        {
            Debug.Log("File does not exist");
            return default(T);
        }

        //Load saved Json
        byte[] jsonByte = null;
        try
        {
            jsonByte = File.ReadAllBytes(tempPath);
            Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\"));
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\"));
            Debug.LogWarning("Error: " + e.Message);
        }

        //Convert to json string
        string jsonData = Encoding.ASCII.GetString(jsonByte);

        //Convert to Object
        object resultValue = JsonUtility.FromJson<T>(jsonData);
        return (T)Convert.ChangeType(resultValue, typeof(T));
    }

    public static bool deleteData(string dataFileName)
    {
        bool success = false;

        //Load Data
        string tempPath = Path.Combine(Application.persistentDataPath, "data");
        tempPath = Path.Combine(tempPath, dataFileName + ".txt");

        //Exit if Directory or File does not exist
        if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
        {
            Debug.LogWarning("Directory does not exist");
            return false;
        }

        if (!File.Exists(tempPath))
        {
            Debug.Log("File does not exist");
            return false;
        }

        try
        {
            File.Delete(tempPath);
            Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\"));
            success = true;
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To Delete Data: " + e.Message);
        }

        return success;
    }
}
like image 590
Green_qaue Avatar asked Dec 02 '22 11:12

Green_qaue


1 Answers

In the answer below:

  • companyname = Company name from the Build Settings
  • productname = Product name from the Build Settings

enter image description here

Windows:

C:\Users\<userprofile>\AppData\LocalLow\<companyname>\<productname>

Windows Store:

%userprofile%\AppData\Local\Packages\<productname>\LocalState

Mac:

~/Library/Application Support/companyname/productname

older version of Unity on Mac:

  • ~/Library/Caches folder

  • ~/Library/Application Support/unity.companyname.productname.

Linux:

$XDG_CONFIG_HOME/unity3d/<companyname>/<productname>

which is the-same as

~/.config/unity3d/<companyname>/<productname>

Android:

/Data/Data/com.<companyname>.<productname>/files

with SD card on the Android device:

/storage/sdcard0/Android/data/com.<companyname>.<productname>/files

iOS:

/var/mobile/Containers/Data/Application/<RandomFolderName>/Documents

Example of the RandomFolderName full name:

/var/mobile/Containers/Data/Application/<055811B9-D125-41B1-A078-F898B06F8C58>/Documents

On iOS, you will be given access to the app's sandbox which is the Document folder. You must create folder inside this directory in order to create a new file inside it.


If you have a default data values in a json file, put the file in Assets/Resources folder so that it will be read-only then read it with TextAsset. When the game loads, you can use PlayerPrefs to check if this is the first time the game being loaded.

If this is the first time, use the value from TextAsset.text. If it is not use then value saved with the DataHandler class.

Roughly something like this:

if (PlayerPrefs.GetInt("FIRSTTIMEOPENING", 1) == 1)
{
    Debug.Log("First Time Opening");

    //Set first time opening to false
    PlayerPrefs.SetInt("FIRSTTIMEOPENING", 0);

    //USE TextAsset to load data
    TextAsset txtAsset = (TextAsset)Resources.Load("player", typeof(TextAsset));
    string tileFile = txtAsset.text;
    PlayerInfo pInfo = JsonUtility.FromJson<PlayerInfo>(tileFile);
}
else
{
    Debug.Log("NOT First Time Opening");

    //USE DataHandler to load data
    PlayerInfo pInfo = DataHandler.loadData<PlayerInfo>("player");
}
like image 70
Programmer Avatar answered Dec 04 '22 20:12

Programmer