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 RobertIvaldi · Dec 23, 2014 at 01:04 AM · arrayssavefiledata

Best method to save a multi-dimensional array as a file?

Example;

 bool[,,] data = new bool[4,4,4];

I'm having trouble coming up with a way (or -the- way) of saving something such as the above 3D array to a file. A crude way would be reading and writing from a .txt file where a line of text represents two dimensions;

 1001#0000#1110#0101

And the different lines represent the final dimension;

 1001#0000#1111#0101
 1111#...
 1000#...
 0100#...

If that makes any sense... but I feel like there MUST be an easier way to write/read this kind of data to a file. Like turning it into raw byte data and saving it? Is that possible? I'm not asking for an exact code/method (unless you feel generous), but simply some guidance towards articles where I can learn for myself. Could anyone help point me in the right path towards figuring out how to do the following effectively?

a) Read/Write file data for a 3D array of boolean's

b) Read/Write file data for a 3D array of Color32's

(C# language preferred)

Comment
Add comment · Show 2
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 RobertIvaldi · Dec 23, 2014 at 02:34 AM 0
Share

This answers my exact need! Thank you. If it would not be too much trouble, could I see the deserialize code as well? From there I can sculpt it to my need :) You are a very big help.

avatar image Cherno · Dec 23, 2014 at 02:42 AM 0
Share

I converted my comment to an answer and will post the DS code in a comment under it.

1 Reply

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

Answer by Cherno · Dec 23, 2014 at 02:10 AM

The general method of making a multi-dimensional array "flat" should be obvious:

 bool[] flatBoolArray = new bool[myMultiArray.GetLength(0) * myMultiArray.GetLength(1) * myMultiArray.GetLength(2) * myMultiArray.GetLength(3)];
 
 int i = 0;
 for(int a = 0; a < myMultiArray.GetLength(0); a ++) {
      for(int b = 0; b < myMultiArray.GetLength(1); b ++) {
           for(int c = 0; c < myMultiArray.GetLength(2); c ++) {
                for(int d = 0; d < myMultiArray.GetLength(3); d ++) {
                     flatBoolArray[i] = myMultiArray[a,b,c,d];
                     i ++;
                }
            }
      }
 }

Can also be done with a flat list, of course.

About actually writing it to file: You could use a BinaryFormatter for that to serialize your data and save it in a file.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System.Runtime.Serialization.Formatters.Binary;
 using System.IO;
 
 public static class SaveLoad {
 
     public static Game loadedGame = new Game();
 
     public static void Save(Game saveGame) {
     
         BinaryFormatter bf = new BinaryFormatter();
         FileStream file = File.Create ("C:/Savegames/" + saveGame.savegameName + ".sav"); //you can call it anything you want
         bf.Serialize(file, saveGame);
         file.Close();
         Debug.Log("Saved Game: " + saveGame.savegameName);
 
     }
  }



 

Now, the Save function takes a Game variable, and this is simpl a custom class that is marked as [System.Serializable] and has variables for the saved game name (string), as well as any other kind of data that you want to save (no types particular to Unity are allowed, such as Transforms, Vector3s, GameObjects, however. You need workarounds for that, for example a Vector3 can be represented as three floats instead. Anyway, that is basically all there is to it. In your case, the Game class would have a bool[] variable that holds your flattened md array, which can be serialized without a hitch. Deseializing on game loading is a little bit trickier but if you need help with that I can give you the code as well.

P.S.: a Game class can also hold any kind of your custom classes or lists & arrays thereof, bas long as these are marked as [System.Serializable] as well and for them, the same limitations apply (no Unity types... If they have these, the relevant fields need to be marked as [System.NonSerialized) and would need workaround, too)

P.P.S: The advantage of serializing like this is that the resulting file is basically encrypted and can't be read without using the deserializing function in your game. It's also MUCH faster than writing strings to a txt file :)

Comment
Add comment · Show 6 · 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 Cherno · Dec 23, 2014 at 02:54 AM 0
Share

Here is the code for Deserializing a saved game again:

 public static void Load(string gameToLoad) {
         if(File.Exists("C:/Savegames/" + gameToLoad + ".sav")) {
             BinaryFormatter bf = new BinaryFormatter();
             FileStream file = File.Open("C:Savegames/" + gameToLoad + ".sav", File$$anonymous$$ode.Open);
             loadedGame = (Game)bf.Deserialize(file);
             file.Close();
             Debug.Log("Loaded Game: " + loadedGame.savegameName);
         }
     }

This belongs into the SaveLoad script from the answer above because it uses the loadedGame variable. Once this variable hold a reference to our deserialized Game variable, we can then access this variable as usual. Note that for my own project, I used an array with only three dimensions, so you need to modify the code to correctly increase the iteration variables :) $$anonymous$$y tip is to take a piece of paper and a pen and write the whole loop system down and then think how it works and how a fourth dimension can be added. Shouldn't be too hard with the code below.

 //ClearScene();//If you want, you can call a function like this that just checks each gameobject in the scene wether it is somehow marked as "please don't destroy me if a game is loaded", like a game manager would, or a player object or something. All objects that need to persists. Of course, this would be the same as when switching scenes.
         
         SaveLoad.Load("blubb");//call the Load function and pass it a the name of the saved game file to load. 
 
         Game loadedGame = SaveLoad.loadedGame;//cache our loadedGame variable from the SavedLoad static class
 
 
         int a = 0;
         int b = 0;
         int c = 0;
 
         for(int i = 0; i < loadedGame.flatBoolArray.Length; i ++) {
 
             my$$anonymous$$ultiArray[a,b,c] = loadedGame.flatBoolArray[i];
 
             c++;
 
             if (c == my$$anonymous$$ultiArray.GetLength(2)) {
                 c = 0;
                 if(b < my$$anonymous$$ultiArray.GetLength(1) - 1) {
                     b++;
                 }
                 else {
                     a++;
                     b = 0;
                 }
 
             }
         }


avatar image RobertIvaldi · Dec 23, 2014 at 02:57 AM 0
Share

$$anonymous$$any thanks again! This will go to good use. $$anonymous$$arked as correct answer as well.

avatar image Cherno · Dec 23, 2014 at 02:59 AM 0
Share

$$anonymous$$y pleasure. It took me a long time to get the loop right so it's good that someone else can use it :D

avatar image Cherno · Dec 23, 2014 at 03:05 AM 0
Share

Oh, I jsut noticed that you actually used a three-dimensional array in your example as well.. I somehow assumed you used a fourth dimension :D In that case, the DS code needs no modification, and in the answer, the outermost or innermost cycle can be deleted and the flat array's length isn't multiplied by it as well.

I also recommend taking a look at the Uniter Serializer, a free asset available on the asset store. Very comprehensive and powerful, although for complex projects it's possible that it breaks down and gives errors, and it gets no further updates but hey it's free and it is a great source of information about advanced serializing.

avatar image Haigen · Aug 31, 2015 at 07:50 AM 0
Share

I've followed this and it's been super helpful, however when I try to deserialize it throws me a null error on my array. It reads the loaded array in fine but that loop you have at the end doesn't work for me :(

 for(int i = 0; i < loadedGame.flatBlockArray.Length; i++) 
 {    
     blocks[a,b,c] = loadedGame.flatBlockArray[i];
                     
     c++;
                     
     if (c == blocks.GetLength(2)) 
     {
         c = 0;
         if(b < blocks.GetLength(1) - 1) 
         {
             b++;
         }
         else 
         {
             a++;
             b = 0;
         }
                         
     }
 }

blocks is null and it throws this error: NullReferenceException: A null value was found where an object instance was required.

Show more comments

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

27 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

Related Questions

how to change Application.persistentDataPath? 1 Answer

How can i save objects to a file 1 Answer

How to constantly save game progress? 1 Answer

How do I save and retrieve ordered data? Can I do this with an array? 1 Answer

How to delete everything at Application.persistentDataPath? 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