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;
}
}
In the answer below:
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");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With