Skip to content

Instantly share code, notes, and snippets.

@JeffersonReisPro
Created September 4, 2017 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffersonReisPro/cd0637b741e40655474eda4ae8cc923d to your computer and use it in GitHub Desktop.
Save JeffersonReisPro/cd0637b741e40655474eda4ae8cc923d to your computer and use it in GitHub Desktop.
This example demonstrates how to save and load a "byte array" with more than 200,000 elements using "PlayerPrefs" (3D Utniy) relatively quickly.
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Linq;
/*
This example demonstrates how to save and load a "byte array" with more than 200,000 elements using "PlayerPrefs" (3D Utniy) relatively quickly.
   When you save or load a "byte array" very large, the game may freeze a bit and then back to normal.
In this example we are saving and loading an image. The greater the height and width of the image, the greater will be the "byte array" and the greater will be the game freezing time.
You can modify this example to save other types of array (string, int, float, etc ...).
My blog: http://jeffersonreis-portfolio.blogspot.com.br/
License:
CC0 1.0 Universal (CC0 1.0)
Public Domain Dedication
https://creativecommons.org/publicdomain/zero/1.0/
*/
public class SaveAndLoadByteArray : MonoBehaviour
{
public string imageURL = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
public Renderer rendererObj;
public bool imageToMainTexture = true;
private string mykeySave = "byteArrayToXml";
private byte[] myByteArray;
// Use this for initialization
IEnumerator Start()
{
Debug.Log("Loading...");
WWW www = new WWW(imageURL);
yield return www;
Debug.Log("downloaded");
if (imageToMainTexture == true)
{
rendererObj.material.mainTexture = www.texture;
myByteArray = www.bytes;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
SaveByte(myByteArray, mykeySave);
Debug.Log("byte array length: " + myByteArray.Length);
}
if (Input.GetKeyDown(KeyCode.L))
{
myByteArray = LoadBytes(mykeySave);
Debug.Log("byte array length: " + myByteArray.Length);
Texture2D tex = new Texture2D(2, 2);
tex.LoadImage(myByteArray);
rendererObj.material.mainTexture = tex;
}
}
void OnGUI()
{
GUI.Label(new Rect(10, 10, Screen.width, Screen.height), "Press \"S\" to save and \"L\" to load.");
}
void SaveByte(byte[] byteArray, string key)
{
List<string> idList = new List<string>();
XDocument doc = new XDocument();
//Transforms each element of the byte [] (array) on an element of the XML
doc.Add(new XElement("root", byteArray.Select(x => new XElement("item", x))));
//Lets all string in a line
string xmlString = AllStringToOneLine(doc.ToString());
//------------------------------------------------------
//Maximum number of "char" / letter within a row in the string
int LineLengthMax = 200000;
//Calculates the number of line breaks
int NumberBreaklines = (xmlString.Length / LineLengthMax);
//Debug.Log("NumberBreaklines: " + NumberBreaklines);
//let's take the positions where we put the line break
for (int i = 1; i <= NumberBreaklines; i++)
{
//Calculate where the line break will be inserted
int x = LineLengthMax * i;
//We create line breaks in various positions of the string
xmlString = xmlString.Insert(x, "\n");
}
//------------------------------------------------------
//Transform each line in an element of the "List"
idList = xmlString.Split(new[] { "\n" }, StringSplitOptions.None).ToList();
//Saves all the elements of the List / Array
for (int i = 0; i <= idList.ToArray().Length - 1; i++)
{
//Saves the information in bytes (number) in text / XML
PlayerPrefs.SetString(key + i, idList[i]);
}
//Saves the number of elements of the List / Array
PlayerPrefs.SetInt(key + "size", idList.ToArray().Length);
Debug.Log("saved");
}
byte[] LoadBytes(string key)
{
byte[] byteArray;
string loadedStr = "";
//reloads the number of lines
int a = PlayerPrefs.GetInt(key + "size");
for (int i = 0; i <= a - 1; i++)
{
//It carries all the information in bytes (number) in text / XML
loadedStr += PlayerPrefs.GetString(key + i);
}
//Transforms the text into an XML document
XDocument doc = XDocument.Parse(loadedStr);
// counts direct children of the root element
//int childrenCount = doc.Root.Elements().Count();
//Debug.Log("children Count: " + childrenCount);
//=====================================================
//Turns every element of the XML an element to the "var int array"
var array = doc.Descendants("item").Select(x => (int)x).ToArray();
//Debug.Log("array index 0: " + array[0]);
//Debug.Log("array last index: " + array[array.Length - 1]);
//Debug.Log("var array size: " + array.Length);
//=====================================================
//Transforms each element of the "int array" an element to the "byte array"
byteArray = array.Select(x => (byte)x).ToArray();
//Debug.Log("byteArray size: " + byteArray.Length);
//Debug.Log("byteArray index 0: " + byteArray[0]);
//Debug.Log("byteArray last index: " + byteArray[byteArray.Length - 1]);
Debug.Log("Loaded");
return byteArray;
}
string AllStringToOneLine(string word)
{
string charRepalcedSpace = " ";
// Remove excess spaces
Regex rgx = new Regex("\\s+");
// replace multiple spaces by a space
return word = rgx.Replace(word, charRepalcedSpace);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment