Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by spinnerbox · Dec 10, 2015 at 11:41 AM · singletonfile-iodata storageloading filegame save

Using singleton pattern - cannot access private/protected method which is public

I made a GameState class in C# that serves as a save/load game data tool. I used singleton pattern as explained in this video: https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/persistence-data-saving-loading

All works in play mode inside unity (Unity 5.1.4) and I don't get any errors. However when I build my game the development console opens showing error that GenerateExp.cs script cannot access private/protected method from GameState.cs script. The method is called Load() and it is btw

 public void Load();

not private or protected as the error says. What could be possibly going on? I thought maybe it could be initialization problem so I placed the GameState game object which holds GameState.cs script component at top of my scene list.

Here are some code samples:

GameState.cs

 public Class GameState : MonoBehaviour 
 {
       public static GameState gameState;
       public float experience;
       public float score;

       void Awake () 
   {
      if (gameState == null) 
       {
         DontDestroyOnLoad(gameObject);
         gameState = this;
     }
     else if (gameState != this) 
     {
         Destroy(gameObject);
     }
   }
       public void Load()
       {
          // specifically it complains about File.Exists part
          if(File.Exists(Application.persistentDataPath + Helper.GAME_DATA_FILE_NAME))
          {
                BinaryFormatter bf = new BinaryFormatter();
            FileStream fs = File.Open(Application.persistentDataPath + Helper.GAME_DATA_FILE_NAME, FileMode.Open);
     GameData data = (GameData)bf.Deserialize(fs);
             
     experience = data.experience;
     score = data.score;

             fs.Close();
                
          }
          // check if file exists, then load data from file on disk. 
          //If not create new file with default data
        }
 
       public void Save()
      {
         // save game data to file on disk
      }
 }
 // in the same file GameState.cs
     [Serializable]
     class GameData 
     {
     public float experience = 0;
     public float score = 0;
     }

GenerateExp.cs

 public class GenerateExp: MonoBehaviour
 {
        public float experience;
        public float score;
       void Awake ()
       {
           GameState.gameState.Load(); // this is the line where the code break in the build
         
            experience = GameState.gameState.experience;
            score = GameState.gameState.score;
        }
 }

Comment
Add comment · Show 4
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 Bonfire-Boy · Dec 10, 2015 at 11:52 AM 0
Share

when I build my game the development console opens showing error that GenerateExp.cs script

When you build your game in what?

avatar image spinnerbox Bonfire-Boy · Dec 10, 2015 at 11:56 AM 0
Share

I build for Web. I also know that this will not work for web. Could this be the problem, saving the file to web server?

avatar image Bunny83 · Dec 10, 2015 at 12:18 PM 0
Share

Next time please post your real code (you can still trim it but your posted code here has too many errors). Also please copy and paste the real error from the bottom console area. A lot people misinterpret the error and relay it wrong. So next time post the complete error.

avatar image spinnerbox Bunny83 · Dec 10, 2015 at 12:38 PM 0
Share

Will delete the question. It seem File API is not available when building for Web.

2 Replies

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

Answer by spinnerbox · Dec 11, 2015 at 09:48 AM

So if you publish to Web, use PlayerPrefs class. It has the same purpose as SharedObject had for Flash/AS3 in Web. 1MB of data available, for strings, ints, floats = HTML5 storage.

However, if you publish to other platforms use, BinaryFormatter and FIleStream to serialize or deserialize data to local file on disk.

Here is my code:

 using UnityEngine;
 using System;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.IO;
 
 public class SaveLoadGameData : MonoBehaviour 
 {
     public static SaveLoadGameData gameState;
     
     public float experience = 0;
     public float score = 0;
     
     void Awake () 
     {
         if (gameState == null) 
         {
             DontDestroyOnLoad(gameObject);
             gameState = this;
         }
         else if (gameState != this) 
         {
             Destroy(gameObject);
         }
     }
     
     public void Save ()
     {
         switch(Helper.BUILD_TYPE)
         {
             case Helper.BUILD_FOR_WEB:
                 PlayerPrefs.SetFloat(Helper.EXP_KEY, experience);
                 PlayerPrefs.SetFloat(Helper.SCORE_KEY, score);
                 break;
                 
             case Helper.BUILD_FOR_WIN_X86:
                 BinaryFormatter bf = new BinaryFormatter();
                 FileStream fs = File.Create(Application.persistentDataPath + Helper.GAME_DATA_FILE_NAME);
                 
                 GameData data = new GameData();
                 data.experience = experience;
                 data.score = score;
                 
                 bf.Serialize(fs, data);
                 fs.Close();
                 break;
                 
             default:
                 Debug.Log("Save method: " + Helper.WRONG_BUILD_TYPE_SELECTED_ERR);
                 break;
         }
     }
     
     public void Load ()
     {
         switch(Helper.BUILD_TYPE)
         {
             case Helper.BUILD_FOR_WEB:
                 experience = PlayerPrefs.GetFloat(Helper.EXP_KEY, 0);
                 score = PlayerPrefs.GetFloat(Helper.SCORE_KEY, 0);
                 break;
                 
             case Helper.BUILD_FOR_WIN_X86:
                 if (File.Exists(Application.persistentDataPath + Helper.GAME_DATA_FILE_NAME))
                 {
                     try
                     {
                         BinaryFormatter bf = new BinaryFormatter();
                         FileStream fs = File.Open(Application.persistentDataPath + Helper.GAME_DATA_FILE_NAME, FileMode.Open);
                         GameData data = (GameData)bf.Deserialize(fs);
                         
                         experience = data.experience;
                         score = data.score;
                         
                         fs.Close();
                     } 
                     catch (Exception e)
                     {
                         Debug.Log(e.Message);
                     }
                 }
                 else
                 {
                     // TODO
                     Save();
                 }
                 break;
 
             default:
                 Debug.Log("Load method: " + Helper.WRONG_BUILD_TYPE_SELECTED_ERR);
                 break;
         }
     }
     
     public void ResetGameState () 
     {
         experience = 0;
         score = 0;
         
         Save();
     }
 }
 
 [Serializable]
 class GameData
 {
     public float experience = 0;
     public float score = 0;
 }

Comment
Add comment · 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
1

Answer by Bunny83 · Dec 10, 2015 at 12:09 PM

Your example code doesn't seem to be your real code. First you have written "Class" with a capital letter. This wouldn't compile at all.

Second you have two classes inside your "GameState.cs" file:

  • The public class "GameState"

  • The private class "GameData"

Inside your "GenerateExp" class you use

 GameData.gameState.Load();

which doesn't make any sense as the GameData class is private and it doesn't contain a static "gameState".

Likewise the following two lines are similar:

 experience = GameState.gameState.experience;
 score = GameState.gameState.score;

Here you correctly access the singleton instance of your GameState class, but then you try to access a "experience" and "score" variable which doesn't exist in your GameState class.

You should do the following:

  • The GameData class should be public

  • You probably want to add a public variable of type GameData to your GameState class. Lets call it "data".

  • When you want to call "load" you have to use GameState.gameState.Load();

  • To access the "experience" variable you have to use GameState.gameState.data.experience

To sum up:

 [Serializable]
 public class GameData 
 {
     public float experience = 0;
     public float score = 0;
 }
 
 public Class GameState : MonoBehaviour 
 {
     public static GameState gameState;
     public GameData data;
     // ....

And the usage would be something like:

 GameState.gameState.Load();
 experience = GameState.gameState.data.experience;
 score = GameState.gameState.data.score;

Note: Your code won't compile, no matter if you build your game or not. If that's your real code must have compiler errors in Unity.

edit
Just saw your edit and comment above. You can't use any method that uses files on the local machine when you build for web (WebGL or Webplayer). Just forget about the "File" class. It can't be used. If you have a server you have to use some serverside script which you can reach using the WWW class.

See the example for ServerSide Highscores on the wiki.

However when you try using the File class you should als get compiler errors. You really should check your console...

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 spinnerbox · Dec 10, 2015 at 12:15 PM 0
Share

Yes the errors you found are typos. Will repair the post.

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

31 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

What is the best solution to load models at runtime? 1 Answer

Is Xcode [documentsDirectory ...] the same as Unity's Application.persistentDataPath? 0 Answers

Game object not enabled after SetActive(true). 1 Answer

Singleton Class 1 Answer

Tracking Turns in Turn Based Game Loop 1 Answer


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