Inheritance Problems I Think

Hello,

Currently I am making save data for my game and I am having problem with save data Inheritance. I have a class called save data which currently has 1 string called name and i have another script called player save data which inherences from save data.

Right now my code finds all the player save data in a folder and sets it as savedata. However, when I do the savedata as playersavedata it loses all data inside the class. For example the name that save data holds is fine until I do the savadata as playersavedata to turn it into player save data it loses everything and becomes null.

Thanks for your time!!

as casts return null when the type isn’t a valid cast.

You don’t show how you are serialising this data but I’d wager it probably doesn’t support polymorphism.

That said, why do you need inheritance here? Inheritance should be about behaviour, not data. If you want different save data for the player, have a different type.

1 Like

Just write

Debug.Log(saveData.GetType());

(and outcomment the line below to avoid throwing an exception)
Then you know how many saveData entries you have in your list and which classes they have (this will also be the class you can cast to).

2 Likes

Thanks for the response,

I am using inheritance because I like them better and it requires less code and more efficient. If all my saved data had variables instead of having to put it on every save data class I can just put it onto the parent class. And I wont need a function to load every single type of save data.

That said here is the class that holds the functions shown on the post

public class SaveDataFileWriter
{
    public string SaveDataDirectoryPath = "";
    public string SaveDataFileName = "";

    public bool CheckToSeeIfSaveDataFileExists()
    {
        if (File.Exists(Path.Combine(SaveDataDirectoryPath, SaveDataFileName)))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public void DeleteSaveDataFile()
    {
        File.Delete(Path.Combine(SaveDataDirectoryPath, SaveDataFileName));
    }

    public void CreateSaveDataFile(SaveData saveData)
    {
        if(SaveDataDirectoryPath == "")
        {
            Debug.LogError("SAVE DATA DIRECTORY PATH IS SET TO NOTHING... PLEASE SET IT TO THE SAVE DATA DIRECTORY PATH");

            return;
        }

        if (SaveDataFileName == "")
        {
            Debug.LogError("SAVE DATA FILE NAME IS SET TO NOTHING... PLEASE GIVE THE FILE A NAME");

            return;
        }

        string savePath = Path.Combine(SaveDataDirectoryPath, SaveDataFileName + ".sav");

        try
        {
            Directory.CreateDirectory(Path.GetDirectoryName(savePath));
            Debug.Log("CREATING SAVE FILE, AT SAVE PATH: " + savePath);

            string dataToStore = JsonUtility.ToJson(saveData, true);

            using (FileStream stream = new FileStream(savePath, FileMode.Create))
            {
                using (StreamWriter fileWriter = new StreamWriter(stream))
                {
                    fileWriter.Write(dataToStore);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogError("ERROR WHILE TRYING TO CREATE SAVE DATA, GAME NOT SAVED!" + savePath + "/n" + ex);
        }
    }

    public SaveData LoadSaveDataFile()
    {
        SaveData saveData = null;

        string loadPath = Path.Combine(SaveDataDirectoryPath, SaveDataFileName);

        if (File.Exists(loadPath))
        {
            try
            {
                string dataToLoad = "";

                using (FileStream stream = new FileStream(loadPath, FileMode.Open))
                {
                    using(StreamReader reader = new StreamReader(stream))
                    {
                        dataToLoad = reader.ReadToEnd();
                    }
                }

                saveData = JsonUtility.FromJson<SaveData>(dataToLoad);
            }
            catch(Exception ex)
            {
                Debug.LogError("FILE COUND NOT BE LOADED" + "/n" + ex);
            }
        }

        return saveData;
    }

    public List<SaveData> LoadAllSaveDataFiles(string directoryRootPath)
    {
        List<SaveData> SaveDatas = new List<SaveData>();

        if (Directory.Exists(directoryRootPath))
        {
            DirectoryInfo directoryInfos = new DirectoryInfo(directoryRootPath);
            foreach (FileInfo file in directoryInfos.GetFiles("*.sav"))
            {
                SaveDataDirectoryPath = directoryRootPath;
                SaveDataFileName = file.Name;

                SaveData saveData = LoadSaveDataFile();

                if (saveData != null)
                {
                    SaveDatas.Add(saveData);
                }
                else
                {
                    Debug.LogError("SAVE DATA IS NULL");
                }
            }
        }

        return SaveDatas;
    }
}

Right it looks like you’re using JsonUtility, which I don’t think supports polymorphism on the root object. You’d probably need to wrap it in another object, and ensure the SaveData field is serialised with [SerializeReference], otherwise there won’t be any by-reference serialisation.

In any case, deserialising as a base type and then immediately up-casting it is a habit you should not form. Either just deserialise it as the correct derived type, or don’t use inheritance here.

1 Like