简体   繁体   中英

How can I add a score from a level to a currency outside of said level when the level ends?

I have an int variable called "Stash". When I beat the level, the game will save. When it saves, I want Stash goes up by however much my score was that level. Currently, my code isn't saving my stash value, and it just sets it to "0(stash default) + Score(whatever my score was that level)." How can I write within this code to make my goal happen?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[RequireComponent(typeof(GameData))]
public class SaveScript : MonoBehaviour
{
    private GameData gameData;
    private string savePath;

    void Start()
    {
        gameData = GetComponent<GameData>();
        savePath = Application.persistentDataPath + "/gamesave.save";
    }

    public void SaveData()
    {
        var save = new Save()
        {
            SavedStash = gameData.Stash + gameData.Score      //<------ (This code)
        };

        var binaryFormatter = new BinaryFormatter();
        using (var fileStream = File.Create(savePath))
        {
            binaryFormatter.Serialize(fileStream, save);
        }

        Debug.Log("Data Saved");
    }

    public void LoadData()
    {
        if (File.Exists(savePath))
        {
            Save save;

            var binaryFormatter = new BinaryFormatter();
            using (var fileStream = File.Open(savePath, FileMode.Open))
            {
                save = (Save)binaryFormatter.Deserialize(fileStream);
            }
            gameData.Stash = save.SavedStash;              //<---------- (and this code)
            gameData.ShowData();

            Debug.Log("Data Loaded");
        }
        else
        {
            Debug.LogWarning("Save file doesn't exist");
        }
    }
}

Also relevant stuff in my GameData file:

    public int Stash { get; set; }
    public int StashNew { get; set; }
    public int Score { get; set; }

The StashNew was just an idea I had to get the whole thing working.

First of all: Never simply use + "/" for system file paths!

Different target devices might have different file systems with different path separators.

Rather use Path.Combine which automatically inserts the correct path separators depending on the OS it is running on.

savePath = Path.combine(Application.persistentDataPath, "gamesave.save");

Then to the main issue:

Properties like

public int Stash { get; set; }
public int StashNew { get; set; }
public int Score { get; set; }

are not de-/serialized by the BinaryFormatter !

Therefore when you do

binaryFormatter.Serialize(fileStream, save);

the numbers are not even written to the output file!

Then when reading in the same thing doesn't work and your properties simply keep the int default value of 0 .


Simply remove these { get; set; } { get; set; } { get; set; } in order to convert your properties into serializable Fields and you should be fine.

public int Stash;
public int StashNew;
public int Score;

Just for the demo I used this code

public class MonoBehaviourForTests : MonoBehaviour
{
    [SerializeField] private GameData In;
    [SerializeField] private GameData Out;

    [ContextMenu("Test")]
    private void Test()
    {
        var formatter = new BinaryFormatter();

        using (var fs = File.Open(Path.Combine(Application.streamingAssetsPath, "Example.txt"), FileMode.OpenOrCreate, FileAccess.Write))
        {
            formatter.Serialize(fs, In);
        }

        using (var fs = File.Open(Path.Combine(Application.streamingAssetsPath, "Example.txt"), FileMode.Open, FileAccess.Read))
        {
            Out = (GameData)formatter.Deserialize(fs);
        }
    }

    [Serializable]
    private class GameData
    {
        public int Stash;
        public int StashNew;
        public int Score;
    }
}

As you can see this has also the side-efect that now the fields actually appear in the Inspector and can be edited. I write values only to the In instance and after hitting Test you can see them loaded into the Out instance via the file.

在此处输入图片说明


However in general I wouldn't recommend to use the BinaryFormatter here at all ... it adds a lot of overhead garbage you don't need at all. Simply go for eg JSON or a comparable simple file format like XML or CSV which only store the relevant data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM