I have followed this really helpful YouTube tutorial for save data,
. I have been able to save the player position (once play mode is quit), as well as save the position of an object in scene and whether it has been destoryed or not.
Before I implemented this, I used a scriptable object to store where a player should start in the next scene. So from going from the main world to the inside of a building like in Stardew Valley. This made sure that the player always spawns in the correct place when going from the main world to a building or vice versa.
I currently canât get the two systems to work together as the scriptable object is currently called in start so the player position that is stored on quitting play mode is not be used on the next time it loaded. Iâm doing the save on a player movement script as this made the most sense to me to store the data.
Player movement script:
public class PlayerMovement : MonoBehaviour, IDataPersistence
{
// Variables for player movement
[Header("Player Movement")]
[SerializeField] float speed = 200f;
// For Unity new input system
PlayerInput playerInput;
Vector2 move;
bool interactPressed;
[SerializeField] bool allowHold;
bool singlePress;
Rigidbody2D rb;
[SerializeField] VectorValue startingPosition; //Scriptable object
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
playerInput = GetComponent<PlayerInput>();
}
// Start is called before the first frame update
void Start()
{
transform.position = startingPosition.SavedPlayerPos; //Calling position from scriptable object
}
public void LoadData(GameData data)
{
this.transform.position = data.playerPosition;
}
public void SaveData(ref GameData data)
{
data.playerPosition = this.transform.position;
}
}
File data handler script:
public class FileDataHandler
{
private string dataDirPath = "";
private string dataFileName = "";
private bool useEncryption = false;
public FileDataHandler(string dataDirPath, string dataFileName, bool useEncryption)
{
this.dataDirPath = dataDirPath;
this.dataFileName = dataFileName;
this.useEncryption = useEncryption;
}
public GameData Load()
{
//Path.Combine used to be able to save on different OS
string fullPath = Path.Combine(dataDirPath, dataFileName);
GameData loadedData = null;
if(File.Exists(fullPath))
{
try
{
string dataToLoad = "";
using(FileStream stream = new FileStream(fullPath, FileMode.Open))
{
using(StreamReader reader = new StreamReader(stream))
{
dataToLoad= reader.ReadToEnd();
}
}
if(useEncryption)
{
dataToLoad = EncryptDecrypt(dataToLoad);
}
loadedData = JsonUtility.FromJson<GameData>(dataToLoad);
}
catch (Exception e)
{
Debug.LogError("Error occured when trying to load data to file: " + fullPath + "\n" + e);
}
}
return loadedData;
}
public void Save(GameData data)
{
//Path.Combine used to be able to save on different OS
string fullPath = Path.Combine(dataDirPath, dataFileName);
try
{
//Creates the directory the file will be written to if it is not on the system
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
//Serialize the game data object into JSON
string dataToStore = JsonUtility.ToJson(data, true);
if(useEncryption)
{
dataToStore = EncryptDecrypt(dataToStore);
}
//Write serialized data to the file
using(FileStream stream = new FileStream(fullPath, FileMode.Create))
{
using(StreamWriter writer = new StreamWriter(stream))
{
writer.Write(dataToStore);
}
}
}
catch(Exception e)
{
Debug.LogError("Error occured when trying to save data to file: " + fullPath + "\n" + e);
}
}
}
The tutorial also mentioned but never went over additive scene loading, would this be something I would want to look up for what Iâm doing, as the player can go to different scenes such as buildings?