Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Pflegeleichtt · Apr 28, 2011 at 10:08 AM · javascriptsaveloadserializable

Try to change Variables from js to c#

Hi I use a c# script to save and load. Now i want to access the c# script variables with a Javascript script. But this won't work like i want to.( I moved the cs script in the Standard Asset folder)

SaveDataCS.cs:

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;

public class SaveDataCS : MonoBehaviour { void Start () { } // === This is the info container class === [Serializable ()] public class SaveData : ISerializable { // === Values === // Edit these during gameplay public bool foundGem1 = false; public float score= 42 ;//= 42; public int levelReached = 3; public int[] HighscoreArraySave = new int[10]; //highscorearrsave public int[] MedalArraySave = new int[10]; //medalarrsave public float[] TimeArraySave = new float[10];//timearr public int LevelSave = 0; // level public string PlayerNameSave = "Playername"; // === /Values === // The default constructor. Included for when we call it during Save() and Load() public SaveData () {}

// This constructor is called automatically by the parent class, ISerializable // We get to custom-implement the serialization process here public SaveData (SerializationInfo info, StreamingContext ctxt) { // Get the values from info and assign them to the appropriate properties. Make sure to cast each variable. // Do this for each var defined in the Values section above foundGem1 = (bool)info.GetValue("foundGem1", typeof(bool)); score = (float)info.GetValue("score", typeof(float)); levelReached = (int)info.GetValue("levelReached", typeof(int)); HighscoreArraySave = (int[])info.GetValue("HighscoreArraySave", typeof(int[])); MedalArraySave = (int[])info.GetValue("MedalArraySave", typeof(int[])); TimeArraySave = (float[])info.GetValue("TimeArraySave", typeof(float[])); LevelSave = (int)info.GetValue("LevelSave", typeof(int)); PlayerNameSave = (string)info.GetValue("PlayerNameSave", typeof(string)); }

// Required by the ISerializable class to be properly serialized. This is called automatically public void GetObjectData (SerializationInfo info, StreamingContext ctxt) { // Repeat this for each var defined in the Values section info.AddValue("foundGem1", (foundGem1)); info.AddValue("score", score); info.AddValue("levelReached", levelReached); info.AddValue("HighscoreArraySave",(HighscoreArraySave)); info.AddValue("MedalArraySave",(MedalArraySave)); info.AddValue("TimeArraySave",(TimeArraySave)); info.AddValue("LevelSave",(LevelSave)); info.AddValue("PlayerNameSave",(PlayerNameSave)); } }

// === This is the class that will be accessed from scripts === public class SaveLoad {

public static string currentFilePath = "SaveData.cjc"; // Edit this for different save files

// Call this to write data 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();
 Debug.Log("Gesaved2"+ data);

}

// Call this to load from a file into "data" 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(); Debug.Log("Geladen2" + data); // Now use "data" to access your Values }

}

// === 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 with this JS script it try to access the variables in the SaveData class:

function Update () {
        if (Input.GetKeyUp(KeyCode.S) ){
            SaveDataCS.SaveLoad.Save();  // this works fine
        }
        if (Input.GetKeyUp(KeyCode.L) ){
            SaveDataCS.SaveLoad.Load();  // this works fine too
        }
        if (Input.GetKeyUp(KeyCode.H) ){
            var other : SaveDataCS;
            other = gameObject.GetComponent("SaveDataCS");  // this doesn't work
            print(other.score);
            other.score=10;   // 
        }
        if (Input.GetKeyUp(KeyCode.K) ){
            print(SaveDataCS.score);
            SaveDataCS.score = 10;   // this doesn't work too
        }
    }

I think its the fact that there are to many classes in the C# script. But maybe someone knows a solution. Thanks for answers.

edit1: Both Scripts are on the same GameObject.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Apr 28, 2011 at 11:39 AM

Your problem is that your whole script doesn't work.

  1. SaveDataCS is derrived from MonoBehaviour but it's an empty class (it contains no data or methods)
  2. The nested class SaveData looks right but to access it you have to use the full path: SaveDataCS.SaveData
  3. In your SaveLoad class you try to create a instance of your SaveData class, but that should even fail because of the class is nested and you didn't specified the full classname.
  4. Now the biggest thing: You create a local instance of SaveData during saving you didn't set the members to the values you want to save. Loading looks right so far but at the end you have to do something with the data you've just deserialized. The comment looks like a TODO: remark...
  5. Using the SaveDataCS as component is useless since it doesn't contain any data.
  6. You try to access a variable or field called .score, but as i said SaveDataCS is a empty class.
  7. Finally you even try to access .score like it's a static member of the class, but it doesn't contain any variables.

In the end i can't even figure out where the actual data you want to save should come from. You should rethink your whole concept and make sure you know what you want to save.


edit

public class GameManager : MonoBehaviour
{
    public int currentLevel = 1;
    public float health = 100.0f;
    private string playername = "";
}

Just an example. If you want to save currentLevel and health but not the playername you will create a simple class to act as "transfer-class" that just holds your desired data.

public class SaveGameManager : ISerializable { public int currentLevel; public float health;

 public SaveGameManager() { }

 public SaveGameManager (SerializationInfo info, StreamingContext ctxt)
 {
     currentLevel = (int)info.GetValue("currentLevel", typeof(int));
     health = (float)info.GetValue("health", typeof(float));
 }

 public void GetObjectData (SerializationInfo info, StreamingContext ctxt)
 {
     info.AddValue("currentLevel", currentLevel);
     info.AddValue("health", health);
 }

}

To save or load the state of the GameManager you have to provide the actual data to the Saving class.

public class SaveLoad { public static void Save (string filePath, GameManager manager) { SaveGameManager data = new SaveGameManager (); data.currentLevel = manager.currentLevel; data.health = manager.health;

     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 (string filePath, GameManager manager)
 {
     Stream stream = File.Open(filePath, FileMode.Open);
     BinaryFormatter bformatter = new BinaryFormatter();
     bformatter.Binder = new VersionDeserializationBinder(); 
     SaveGameManager data = (SaveGameManager)bformatter.Deserialize(stream);
     stream.Close();

     manager.currentLevel = data.currentLevel;
     manager.health = data.health;
 }

}

To save the state of your GameManager just do that (JS):

var manager = Getcomponent.<GameManager>();

SaveLoad.Save("SaveData.cjc",manager);

Loading works the same way...
That's all untested... I've just grabbed some of your code and created this example how it should work. The copying process can be packed into the save-container-class to cleanup the code and provide a bit more general purpose saving class.

Hopefully that helps a bit ;)


Sorry for the long post, have a nice day
(greetings from germany ;))

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Pflegeleichtt · Apr 28, 2011 at 12:09 PM 0
Share

Du hast nicht zufllig nen schnes SaveLoad script ;)?

avatar image Bunny83 · Apr 28, 2011 at 03:01 PM 0
Share

Nee, leider nicht ;). Unfortunately i wasn't in need of such a saving method yet. In general binary serialization can be used to save any objects data. You used an extra object to store only relevant data, but you have to copy your actual data into this class before you serialize it and after deserialization you have to copy the data back. I can add a small example.

avatar image
0

Answer by CHPedersen · Apr 28, 2011 at 10:41 AM

Component.gameObject references the GameObject that Component is attached to. So when you write,

other = gameObject.GetComponent("SaveDataCS");

You're asking for a component with the name "SaveDataCS" that is attached to the same GameObject as the JS-script with that line in it. If that GameObject doesn't have a component with that name, other will remain null.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Pflegeleichtt · Apr 28, 2011 at 11:14 AM 0
Share

yes i know, i added both scripts to one gameobject as component

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

C# line into Javascript help 1 Answer

Setting Scroll View Width GUILayout 1 Answer

How to load data from this serializable class? 1 Answer

How can I save and load an entire hashtable using playerprefs, or on all systems.? 1 Answer

Problem with SAVE/LOAD, serializationStream supports seeking, but its length is 0 and Sharing violation on path 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges