1

I'm making a simple game, one of the features is challenges which are going to be opened from a file, here is how one of the challenges look:

[System.Serializable]
public class Challenge10 : ChallegeInterface {
    public bool isCompleted = false;
    public string description = "test";
    public int curCoins;
    public override void giveReward (){
        GameDataSingleton.gameDataInstance.game_data.addCoinsFromReward (7);
    }
    //Method to check if everything is completed
    public override bool isComplete (){ 
        if (!isCompleted) {
            curCoins= GameDataSingleton.gameDataInstance.game_data.getCoinsThisGame ();
            if (curCoins >= 1) {
                isCompleted = true;
                giveReward ();
                return true;
            }
        }
        return false;
    }
}

The problem is that after I deserielize the file the string value(description) is null. Here is the code where the program is opening the challenges.

public void openChallenges(){
        challenges = new ChallegeInterface[game_data.challenges.Length];
        for (int i = 0; i < game_data.challenges.Length; i++) {
            int curChallenge = game_data.challenges[i];
            ChallegeInterface challenge = HddManager.HddManagerInstance.load<ChallegeInterface> ("challenges/challenge"+curChallenge);
            Debug.Log (challenge.description);
            challenges[i] = challenge;
        }
    }

Everything else seems fine, except the description. Am i missing something?

Edit: This is how the program is serializing the object:

public void save<T>(T data, string fileName) where T : class{
        if (fileName == "")
            Debug.Log ("Empty file path");
        FileStream file = null;
        try{
            if(fileName.IndexOf("/") > 0){
                string[] strDirName = fileName.Split(new char[]  {'/'});
                string dirName = strDirName[0];
                if(!Directory.Exists(Path.Combine(Application.persistentDataPath, dirName))){
                    Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, dirName));
                }
            }
            file = File.Create(Path.Combine(Application.persistentDataPath, fileName));
            binFormatter.Serialize(file, data);
            Debug.Log ("File saved succesfully" + fileName);
        }catch(IOException e){
            Debug.Log(e.ToString());
        }finally{
            if(file != null)
                file.Close();
        }
    }

This is how the object is deserialized:

public T load<T> (string fileName) where T : class{ // T => object type
        if (fileName == null) {
            Debug.Log ("Empty path to file");
            return null;
        } else {
            FileStream file = null;
            try {
                //Open the file;
                file = File.Open (constructFilePath(fileName), FileMode.Open);
                //To be removed
                Debug.Log ("File loaded succesfully");
                // Deserialize the opened file, cast it to T and return it
                return binFormatter.Deserialize (file) as T;
            } catch (IOException e) {
                //To be removed
                Debug.Log (e.ToString ());
                // Saves the current object in case the file doesn't exist
                // Use Activator to create instance of the object,
                save (Activator.CreateInstance<T> (), fileName);
                // calls the function again
                return load<T> (fileName);
            } finally {
                //Close the file
                if (file != null)
                    file.Close ();
            }
        }
    }
user3071284
  • 6,955
  • 6
  • 43
  • 57
Planet_Earth
  • 325
  • 1
  • 3
  • 11
  • how are you serialize/desterilizing your object? try use xml serialization instead? – Steve Sep 20 '15 at 18:35
  • I edited the question. As a last resort I will rewrite everyting to use XML, but if it's possible to fix this code, it will be greate. – Planet_Earth Sep 20 '15 at 18:44
  • Weird,it works fine for me, try to debug after the `ChallegeInterface challenge = HddManager.HddManagerInstance.load ("challenges/challenge"+curChallenge);` line and inspect the description manually. Is it still empty? – Tamir Vered Sep 20 '15 at 19:00
  • I think the problem might be that you are trying to serialize an interface. Here is more [info](http://stackoverflow.com/questions/2639362/why-are-interfaces-not-serializable). – fsacer Sep 20 '15 at 19:03
  • 1
    Wait, how do you even do that?: `ChallegeInterface challenge = HddManager.HddManagerInstance.load ("challenges/challenge"+curChallenge); Debug.Log` ***`(challenge.description);`*** **interfaces cannot contain fields**. is it a class? if so, you are checking for the base class' field in the `Debug.Log(challenge.description)` which is empty... – Tamir Vered Sep 20 '15 at 19:03

1 Answers1

1

By inspecting the following lines in the openChallenges() method:

ChallegeInterface challenge = HddManager.HddManagerInstance.load<ChallegeInterface> ("challenges/challenge"+curChallenge);
Debug.Log (challenge.description);

I assume ChallegeInterface is actually a class and not an interface since interfaces can not contain fields and you are accessing challenge.description when challenge is ChallegeInterface which means ChallengeInterface is a class.

In this case you are actually accessing the base class' (ChallegeInterface) field instead of the correct one (Challenge10). and that field is empty.

Important: keep clear and correct coding conventions, never name a class Interface, it's better to avoid naming types with programming terminology instead of indicative naming related to their usage.

P.S.: I've checked the serialization myself and inspected Challenge10's description and it works fine.

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57