Unity + Ink/Inkle: How to load a saved story state JSON - c#

So in our visual novel game using the ink/inkle API for unity, I'm trying to implement a save and load system, but I am currently having trouble with loading the saved state the way I intend to.
Based on the API's documentation, to save the state of your story within your game, you call:
string savedJson = _inkStory.state.ToJson();
then to load it:
_inkStory.state.LoadJson(savedJson);
Here is the how I save the current state of the story using PlayerPrefs, which is working just fine.
public void saveGame()
{
DialogueSystem dialogueSystem = GetComponent<DialogueSystem>();
dialogueSystem.savedJson = dialogueSystem.dialogue.state.ToJson();
PlayerPrefs.SetString("saveState", dialogueSystem.savedJson);
Debug.Log(dialogueSystem.savedJson);
}
and here is how I'm trying to load the saved state on Start(), which doesn't load the saved state.
private void Start()
{
dialogue = new Story(dialogueJSON.text);
currentActiveBG = BGs[0];
historyScript = GetComponent<History>();
counterScript = GetComponent<counter>();
if (PlayerPrefs.HasKey("saveState")) { // for loading the saved state
dialogue = new Story(dialogueJSON.text);
savedJson = PlayerPrefs.GetString("saveState");
dialogue.state.LoadJson(savedJson);
loadLine(); //this function contains story.Continue, which loads the next line
Debug.Log(savedJson);
}
else {
loadGame("Pre_Prep1"); // default starting line
}
}
How can I make this work? And is there a better way of implementing this save/load feature?

I'm not sure which game you're going to make but, I use the following saving system in my project and it's working perfectly and you can also use it.
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Saving System
public class UserData{
#region Save Data Var's
// file Path
private static readonly string FILE_PATH = Application.dataPath +
"/SaveFiles";
public int carToLoad;
public int levelToLoad;
public int unlockLevels;
#endregion
#region Methods
// Save
public static void SaveData(string contents){ // for Car Selection
File.WriteAllText(FILE_PATH + "/UserData.txt",contents);
}
// Load
public static UserData LoadData(){
string _data = File.ReadAllText(FILE_PATH + "/UserData.txt");
return JSONToUserData(_data);
}
// Init
public static void UserData_init(){
CheckFilesPreviousData();
CheckDirectory();
}
// Selection Level Data
public static void SaveData(UserData LevelData) { // for Level
UserData tempObj = LoadData();
tempObj.levelToLoad = LevelData.levelToLoad;
SaveData(UserDataToJSON(tempObj));
}
// UnLock Level Data
public static void SaveUnLockedLevelData(int LevelValue){
UserData tempObj = LoadData();
tempObj.unlockLevels = LevelValue;
File.WriteAllText(FILE_PATH + "/UnLockLevels.text",
UserDataToJSON(tempObj));
}
// Load UnLock Level Data
public static UserData LoadUnLockLevelData(){
string _data= File.ReadAllText(FILE_PATH+"/UnLockLevels.text");
UserData tempObj = JSONToUserData(_data);
return tempObj;
}
#endregion
#region Helper Methods
// !! important
public static UserData JSONToUserData(string path) =>
JsonUtility.FromJson<UserData>(path);// JSON to Obj
public static string UserDataToJSON(UserData obj) => JsonUtility.ToJson(obj);//
Obj to JSON
// Making Directory if not present
private static void CheckDirectory(){
if (!Directory.Exists(FILE_PATH)){
Directory.CreateDirectory(FILE_PATH);
}
}
// Reset Data If User Play 1st Time
private static void CheckFilesPreviousData(){
// Checking File is not Null
UserData tempObj = LoadUnLockLevelData();
if(tempObj == null){
const int FIRSTLEVEL = 1;
SaveUnLockedLevelData(FIRSTLEVEL);
Debug.Log("Donee");
}
}
#endregion
}

Related

Unity - is there a way to show the popup in my game only once per game session?

[EDIT] Everything is working now! Thank's to #MrMoonMan!
As the title says, I'm working on a mobile game and I just implemented a Check Update popup.
The thing is, the popup is displayed every time the menu scene is loaded, and this is very annoying because if the player goes to the weapon menu and then comes back to the main menu 10 times, he will see the popup 10 times. The goal is to have the popup appear only once per game session, Here is what I tried for the moment but without success:
Using a bool variable
Destroy the gameobject to which the checkupdate script is attached when the user presses the "No Thank's" button
Here is the code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class CheckUpdate : MonoBehaviour
{
public string versionUrl = "";
public string currentVersion;
private string latestVersion;
public GameObject newVersionAvailable;
private static bool hasBeenChecked = false;
void OnAwake()
{
DontDestroyOnLoad(this);
StartCoroutine(LoadTxtData(versionUrl));
}
private IEnumerator LoadTxtData(string url)
{
UnityWebRequest loaded = new UnityWebRequest(url);
loaded.downloadHandler = new DownloadHandlerBuffer();
yield return loaded.SendWebRequest();
latestVersion = loaded.downloadHandler.text;
CheckVersion();
}
private void CheckVersion()
{
Debug.Log("currentVersion = " + currentVersion);
Debug.Log("latestVersion = " + latestVersion);
Version versionDevice = new Version(currentVersion);
Version versionServer = new Version(latestVersion);
int result = versionDevice.CompareTo(versionServer);
if ((latestVersion != "") && (result < 0))
{
newVersionAvailable.SetActive(true);
}
if (GetChecked())
return;
}
public void ClosePopUp(GameObject obj)
{
obj.SetActive(false);
Destroy(this);
}
public void OpenURL(string url)
{
Application.OpenURL(url);
}
public static bool GetChecked()
{
if (hasBeenChecked)
{
return hasBeenChecked;
}
hasBeenChecked = true;
return false;
}
}
EDIT
Ok so you mentioned that it still happens every time the scene is reloaded. That is because the object is created when the scene is loaded. It isn't saved between scenes. To handle that properly you need to tell it to not get destroyed when the scene is unloaded and to do that is simple, and that is by Adding DontDestroyOnAwake. Here is an example of the code:
public class CheckUpdate : MonoBehaviour
{
public string versionUrl = "";
public string currentVersion;
private string latestVersion;
public GameObject newVersionAvailable;
void OnAwake()
{
DontDestroyOnLoad(this);
}
void OnStart()
{
StartCoroutine(LoadTxtData(versionUrl));
}
private IEnumerator LoadTxtData(string url)
{
UnityWebRequest loaded = new UnityWebRequest(url);
loaded.downloadHandler = new DownloadHandlerBuffer();
yield return loaded.SendWebRequest();
latestVersion = loaded.downloadHandler.text;
}
private void CheckVersion()
{
Debug.Log("currentVersion = " + currentVersion);
Debug.Log("latestVersion = " + latestVersion);
Version versionDevice = new Version(currentVersion);
Version versionServer = new Version(latestVersion);
int result = versionDevice.CompareTo(versionServer);
if ((latestVersion != "") && (result < 0))
{
newVersionAvailable.SetActive(true);
}
}
public void ClosePopUp(GameObject obj)
{
obj.SetActive(false);
}
public void OpenURL(string url)
{
Application.OpenURL(url);
}
}
,,Menu scene''? It sound some suspicious. If you load and unload whole new scene as menu, state as bool field in MonoBehaviours or modifing the scene structure (destory, create object) will not work beacuse allways will be loaded new scene from scratch. ;)
If you have to have menu on seperated scene use someting other to manage the state. For example:
DontDestoryOnLoad objects.
Or some C# static class or singleton (not a MonoBehaviour).

Learning about Saving and Loading in Unity; encountered error CS1513 for unknown reason

So I've been making a save/load script for my Unity project, and it looks like this (please don't copy):
using UnityEngine;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Runtime.Serialization;
using System.Reflection;
// Made By Wasabi.
// === This is the info container class ===
[Serializable ()]
public class SaveData : ISerializable {
// === Values ===
public bool foundKeyCard1 = false;
public bool foundKeyCard2 = false;
public bool foundKeyCard3 = false;
public bool foundKeyCard4 = false;
public bool foundKeyCard5 = false;
public bool foundKeyCard6 = false;
public bool foundKeyCard7 = false;
public bool foundKeyCard8 = false;
public bool foundKeyCard9 = false;
public bool foundKeyCard10 = false;
public bool foundCarKeys1 = false;
public float expscore = 0;
public int levelReached = 1;
// === /Values ===
public SaveData () {}
public SaveData (SerializationInfo info, StreamingContext ctxt)
{
foundKeyCard1 = (bool)info.GetValue("foundKeyCard1", typeof(bool));
foundKeyCard2 = (bool)info.GetValue("foundKeyCard2", typeof(bool));
foundKeyCard3 = (bool)info.GetValue("foundKeyCard3", typeof(bool));
foundKeyCard4 = (bool)info.GetValue("foundKeyCard4", typeof(bool));
foundKeyCard5 = (bool)info.GetValue("foundKeyCard5", typeof(bool));
foundKeyCard6 = (bool)info.GetValue("foundKeyCard6", typeof(bool));
foundKeyCard7 = (bool)info.GetValue("foundKeyCard7", typeof(bool));
foundKeyCard8 = (bool)info.GetValue("foundKeyCard8", typeof(bool));
foundKeyCard9 = (bool)info.GetValue("foundKeyCard9", typeof(bool));
foundKeyCard10 = (bool)info.GetValue("foundKeyCard10", typeof(bool));
foundCarKeys1 = (bool)info.GetValue("foundCarKeys1", typeof(bool));
expscore = (float)info.GetValue("expscore", typeof(float));
levelReached = (int)info.GetValue("levelReached", typeof(int));
}
public void GetObjectData (SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("foundKeyCard1", (foundKeyCard1));
info.AddValue("foundKeyCard2", (foundKeyCard2));
info.AddValue("foundKeyCard3", (foundKeyCard3));
info.AddValue("foundKeyCard4", (foundKeyCard4));
info.AddValue("foundKeyCard5", (foundKeyCard5));
info.AddValue("foundKeyCard6", (foundKeyCard6));
info.AddValue("foundKeyCard7", (foundKeyCard7));
info.AddValue("foundKeyCard8", (foundKeyCard8));
info.AddValue("foundKeyCard9", (foundKeyCard9));
info.AddValue("foundKeyCard10", (foundKeyCard10));
info.AddValue("foundCarKeys1", (foundCarKeys1));
info.AddValue("expscore", expscore);
info.AddValue("levelReached", levelReached);
}
}
// === This is the class that will be accessed from scripts ===
public class SaveLoad {
public static string currentFilePath = "SaveData.cjc";
public static void Save () // Overloaded
{
Save (currentFilePath);
}
public static void Save (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath, FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
bformatter.Serialize(stream, data);
stream.Close();
}
public static void Load () { Load(currentFilePath); } // Overloaded
public static void Load (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath, FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
data = (SaveData)bformatter.Deserialize(stream);
stream.Close();
}
}
// === This is required to guarantee a fixed serialization assembly name, which Unity likes to randomize on each compile
// Do not change this
public sealed class VersionDeserializationBinder : SerializationBinder
{
public override Type BindToType( string assemblyName, string typeName )
{
if ( !string.IsNullOrEmpty( assemblyName ) && !string.IsNullOrEmpty( typeName ) )
{
Type typeToDeserialize = null;
assemblyName = Assembly.GetExecutingAssembly().FullName;
// The following line of code returns the type.
typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) );
return typeToDeserialize;
}
return null;
}
}
And I think that's it. The CS1513 isn't in there. If you spot any errors, please let me know. But the problem is in this other script I'm making that autosaves when I close the application. It looks like this (Please don't copy):
using UnityEngine; // For Debug.Log, etc.
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Runtime.Serialization;
using System.Reflection;
// Made by Wasabi.
void OnApplicationQuit()
{
public class SaveLoad {
public static string currentFilePath = "SaveData.cjc";
public static void Save () // Overloaded
{
Save (currentFilePath);
}
public static void Save (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath,
FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new
VersionDeserializationBinder();
bformatter.Serialize(stream, data);
stream.Close();
}
}
}
Now I know the code under void OnApplicationQuit() is supposed to be my save routine. Well I'm not exactly sure what part of my save script is my save routine. So If you could help me with that, feel free to examine my save/load script and tell me what is my actual save routine. But anyways, it keeps on telling me "Error, "}" expected (11,7) CS1513." and I check my script. I've read another post and the answer was that the error meant that I had forgotten a closing "}" at the end f my script. Well it seems as though that is not true in my case, because it is not missing any "}". I even tried adding an extra "}" at the end, and yet it still said the same thing. So it only clears the error when I put another "}" directly after the opening "{" after
void OnApplicationQuit() which doesn't make any sense. But when I do, it then says another error at
void OnApplicationQuit() (to be specific: the beginning of OnApplicationQuit() of void OnApplicationQuit()) and that I can't use methods or functions for that namespace, which I don't know what that means, and I don't think that's true. I believe that the second error is only triggered because I had to put void OnApplicationQuit() {}. What is going on here and how in the world do I fix it? Another thing: I constructed my Save/Load script after researching on how to do that, but how does the code know when I collect a keycard1? Do I have to make a script in the keycard1 that tells the Save/Load script when I collect it? And will this result in me having to add more scripts in the Save/Load script to detect the keycard1 script telling the Save/Load script that I picked it up? I'm still new to the whole C# part of Unity and I'm entirely self-taught. You see, I'm just beginning to make my first serious project. So I need to know what exactly are the save and load routines in my save/load script that I use to call save and load; because I need to make a menu screen with buttons that when pressed, call the save or load routine. So when I press he Save or Load button(s), looking at my script, will the Script know that I have the KeyCard, or will I have to manually put that into the script? And lastly, how do I make a script that calls a save when I obtain, say, KeyCard2?
Sincerely,
Wasabi.
Please don't copy
I assure you that I don't even want to ^^
What is your second snippet supposed to do?
You have a method declaration OnApplicationQuit() and within that method you declare public static fields and other methods.
-> None of this is allowed in c#.
your method OnApplicationQuit() should be inside of a type of type MonoBehaviour {...}
and then you can't have access modifiers inside a method. You rather want to simply call that static method SaveLoad.Save().
You would rather have a GameObject in your scene with a component attached like
public class SaveLoadBehavior : MonoBehaviour
{
private void Awake ()
{
SaveLoad.Load();
}
void OnApplicationQuit()
{
SaveLoad.Save();
}
}
See OnApplicationQuit.
Note herefor that every component in Unity needs to be written in a individual and equally named file. So in the example it should be in SaveLoadBehaviour.cs (where the .cs is hidden inside Unity)
Actually alternative to this you might want to rather use e.g. RuntimeInitializeOnLoadMethod and Application.quitting this way you don't need the afore mentioned component and GameObject at all:
public class SaveLoad
{
// will be automatically called on application start
[RuntimeInitializeOnLoadMethod]
private static void Init()
{
Load();
// register a callback to the application quitting event
Application.quitting += OnQuit;
}
// will be automatically called on application quit
private static void OnQuit()
{
Save();
}
.... // Your load and save methods just the way you have them already
}

Don't Destroy on Load Object and GameData

I want to save my game data as my 2D game progresses using a DontDestroyOnLoad object.
I have a GameData class/script which stores values like health, magicType, etc, a SaveLoad class/script which saves current values in the GameData class to Json and an empty game object called PlayerData that has both of the above scripts.
Currently, I'm saving values in one scene by using button click events. My object attached to the button is the PlayerData object, and I change values using the GameData script on the click event.
But this only works on the first scene - I can't attach the PlayerData object and store its GameData values because there is no PlayerData object in the editor.
So how can I attach this object, which is in a different scene? Or am I doing this wrong?
Here's a photo of my current project.
Also, when I save a boolean, then open my Json file, the file is empty. Is this normal? Here's my save and load code:
Load:
private string _filePath;
private static DataService _instance;
public DataService Instance
{
get { return _instance; }
}
public GameData _gameData;
private void Awake()
{
DontDestroyOnLoad(gameObject);
}
public void LoadGameData()
{
_filePath = Path.Combine(Application.persistentDataPath, "GameData1.json");
string json;
if (File.Exists(_filePath))
{
json = File.ReadAllText(_filePath);
JsonUtility.FromJsonOverwrite(json, _gameData);
}
else
{
Debug.Log("File missing.");
}
}
Save:
public void SaveGameData1()
{
string json = JsonUtility.ToJson(_gameData);
_filePath = Path.Combine(Application.persistentDataPath, "GameData1.json");
if (File.Exists(_filePath))
{
File.Create(_filePath).Dispose();
}
File.WriteAllText(_filePath,json);
}
EDIT: This is the code of my GameData class:
[Serializable]
public class GameData : MonoBehavior
{
public float Health { get; set; }
}
Data Path
First of all as just recently answered here I wouldn't use the persistentDataPath for development but rather the streamingAssetsPath and on first app run copy the file over.
Singleton Pattern
I see you have the first half of a Singleton pattern but: You never assigned a value to instance. I usually would do it "lazy" in the property or Awake like e.g.
private static DataService instance;
public static DataService Instance
{
if(instance) return instance;
instance = FindObjectOfType<DataService>();
if(instance) return instance;
// If it wasnt found in the scene create it now
instance = new GameObject("DataService", typeof (GameData)). AddComponent<DataService>();
instance._gameData = instance.GetComponent<GameData>();
DontDestroyOnLoad (instance.gameObject);
return instance;
}
private void Awake ()
{
if(instance && instance != this)
{
Debug.LogWarning("Another instance of DataService I already in use");
Destroy(gameObject);
return;
}
if(instance) return;
instance = this;
DontDestroyOnLoad (gameObject);
if(!_gameData) _gameData = GetComponent<GameData>();
}
Or static Class
Actually with the code you provided I doubt that any of your two classes really needs to be a MonoBehaviour!
You could probably simply use something like
public static class DataService
{
private const string FILE_NAME = "GameData1.json";
public static GameData GameData = new GameData();
public static void SaveGameData1()
{
var json = JsonUtility.ToJson(_gameData);
var filePath = Path.Combine(Application.persistentDataPath, FILE_NAME);
if (File.Exists(filePath))
{
File.Create(filePath);
}
File.WriteAllText(filePath,json);
}
public static void LoadGameData()
{
var filePath = Path.Combine(Application.persistentDataPath, FILE_NAME);
if (File.Exists(filePath))
{
var json = File.ReadAllText(_filePath);
JsonUtility.FromJsonOverwrite(json, GameData);
}
else
{
Debug.Log("File missing.");
}
}
}
and
[Serializable]
public class GameData
{
public float SomeValue;
...
}
Now you can from everywhere simply call
DataService.LoadGameData();
And then access value like
DataService.GameData.SomeValue = ...;
For the buttons
I would create a class DataServiceButton which is attached to a UI.Button and registers itself as a listener to onClick like
[RequireComponent(typeof(UI.Button))]
public class DataServiceButton : MonoBehaviour
{
public enum ButtonType
{
Save,
Load
}
// This is set via the Inspector
[SerializeField] private ButtonType type;
// Here you can already reference the according Button component
[SerializeField] private Button button;
private void Awake()
{
if(!button) button = GetComponent<Button>();
// Register as callback
button.onClick.AddListener(HandleClick);
}
private void HandleClick()
{
switch(type)
{
case ButtonType.Load:
DataService.LoadGameData();
// OR IF YOU STICK TO THE SINGLETON
//DataService.Instance.LoadGameData();
break;
case ButtonType.Save:
DataService.SaveGameData();
// OR ACCORDINGLY WITH SINGLETON
//DataService.Instance.SaveGameData();
break;
}
}
}
The question why your file is empty after writing data unfortunately can not be answered without seeing the code of your GameData class...
Make sure your types are serializeable.

How to save raw data as text file/json?

So I'm only a week into learning C# and I've been working on this one problem for 8 hours. I'll describe what I'm trying to do, and if there's a better way I would really appreciate any guidance.
In the code below, I'm storing info from a Firebase database called snapshot, and trying to save it as a text file data.json. Later in the code, it reads data.json and calls allRoundData from the file.
Right now in Unity the application doesn't compile and says "Object reference not set to an instance of an object" for allRoundData = loadedData.allRoundData;
I also checked and nothing is writing to the text file when I open it in explorer.
I'm pulling trivia questions and answers from a Firebase database, so however I do this it's important that the user can't access the answers. Would it be more secure to skip writing it to a text file and just declare allRoundData = snapshot.allRoundData? The problem is that allRoundData is a string array and the snapshot is an object. Is there a way to easily convert it or how can I solve this in the simplest way?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.IO;
using Firebase;
using Firebase.Unity.Editor;
using Firebase.Database;
public class DataController : MonoBehaviour
{
public class FirebaseStart: MonoBehaviour
{
void Start()
{
// Set up the Editor before calling into the realtime database.
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://FIREBASEDATABASE");
// Get the root reference location of the database.
DatabaseReference reference =
FirebaseDatabase.DefaultInstance.RootReference;
FirebaseDatabase.DefaultInstance
.GetReference("allRoundData")
.GetValueAsync().ContinueWith(task => {
if (task.IsFaulted)
{
// Handle the error...
}
else if (task.IsCompleted)
{
string gameDataFileName = "data.json";
string filePath =
Path.Combine(Application.streamingAssetsPath, gameDataFileName);
DataSnapshot snapshot = task.Result;
// Do something with snapshot...
string rawData = snapshot.GetRawJsonValue();
StreamWriter sw = new StreamWriter(filePath);
sw.WriteLine(rawData);
sw.Close();
}
});
}
}
private RoundData[] allRoundData;
private PlayerProgress playerProgress;
// Use this for initialization
void Start ()
{
DontDestroyOnLoad(gameObject);
LoadGameData();
LoadPlayerProgress();
SceneManager.LoadScene("MenuScreen");
}
public RoundData GetCurrentRoundData()
{
return allRoundData [0];
}
public void SubmitNewPlayerScore(int newScore)
{
if (newScore > playerProgress.highestScore)
{
playerProgress.highestScore = newScore;
SavePlayerProgress();
}
}
public int GetHighestPlayerScore()
{
return playerProgress.highestScore;
}
// Update is called once per frame
void Update () {
}
private void LoadPlayerProgress()
{
playerProgress = new PlayerProgress();
if (PlayerPrefs.HasKey("highestScore"))
{
playerProgress.highestScore = PlayerPrefs.GetInt("highestScore");
}
}
private void SavePlayerProgress()
{
PlayerPrefs.SetInt("highestScore", playerProgress.highestScore);
}
private void LoadGameData()
{
string gameDataFileName = "data.json";
string filePath = Path.Combine(Application.streamingAssetsPath, gameDataFileName);
if (File.Exists(filePath))
{
string dataAsJson = File.ReadAllText(filePath);
GameData loadedData = JsonUtility.FromJson<GameData>(dataAsJson);
allRoundData = loadedData.allRoundData;
}
else
{
Debug.LogError("Cannot load game data!");
}
}
}

Saving a Class of my variables to XML File

I have created a Class called "VNCVars.cs" and I want to be able to Save the data associated with all the Variables inside VNCVars to a XML file so I can load them back in on startup. I have another class called "SaveData.cs" which contains the code to generate the XML file.
I have code written that runs but my XML file is always empty.....can somebody point out what I have missed out??
public class VNCVars
{
//Global Variables for VNC 1 Location
//VNC File Location 1 Get and Set routines
private static string strVNC1Location;
public static string VNC1Location
{
get { return strVNC1Location; }
set { strVNC1Location = value; }
}
//Global Variables for VNC 2 Location
//VNC File Location 2 Get and Set routines
private static string strVNC2Location;
public static string VNC2Location
{
get { return strVNC2Location; }
set { strVNC2Location = value; }
}
//Global Variables for VNC 3 Location
//VNC File Location 3 Get and Set routines
private static string strVNC3Location;
public static string VNC3Location
{
get { return strVNC3Location; }
set { strVNC3Location = value; }
}
}
public class SaveXML
{
public static void SaveData()
{
var SaveData = new VNCVars();
XmlSerializer sr = new XmlSerializer(typeof(VNCVars));
TextWriter writer = new StreamWriter(#"c:\Fanuc\SetupVars.xml");
sr.Serialize(writer, SaveData);
writer.Close();
}
}
Then finally on my form I currently just have a button and on the click the following occurs...
private void button2_Click(object sender, EventArgs e)
{
SaveXML.SaveData();
}
Any help greatly appreciated....
You should use instance properties instead of static properties.
You can then use the singleton pattern to keep only one instance of this class.
If you need to have static variables and don't want to make this class a singleton, the way around is to wrap static variables:
[XmlElement("VNC1Location")]
public string VNC1LocationLocal
{
get
{
return VNC1Location;
}
set
{
VNC1Location = value;
}
}

Categories

Resources