I want to make a save file. It’s not the first file I’m creating, but this time I encounter an error that I have never encountered before - script doesn’t put data into file.
Here’s data I want to save :
using System;
using System.Collections.Generic;
[Serializable] public class SaveInfo {
public List<int> infosInt = new List<int>();
public List<bool> infosBool = new List<bool>();
public List<List<int>> planets = new List<List<int>>();
public List<float> positions = new List<float>();
public List<string> names = new List<string>();
public float posX;
public float posY;
public int credits, resources, fuel;
public float HP;
}
Here’s script that doesn’t work :
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
public class GalaxyGenerator : MonoBehaviour {
int number;
public GameObject starPrefab;
public static SaveInfo info;
public GameObject loading, notLoading;
public AudioSource music;
GameObject newStar;
public GameObject markerSprite, marker, circle;
public Sprite goIn, goOut;
GameObject ClosestStar() //It's neccessary for stars not to ocupy the same place
{
GameObject[] stars = GameObject.FindGameObjectsWithTag("Star");
GameObject star = null;
float d = float.PositiveInfinity;
if (stars != null)
{
foreach (GameObject go in stars)
{
float nd = Vector3.Distance(go.transform.position, newStar.transform.position);
if (nd < d)
{
d = nd;
star = go;
}
}
}
return star;
}
void Start () { //Circle and marker indicate player position in galaxy
if (File.Exists(Application.dataPath + "/SAVEGAME"))
{
Stream stream = File.Open(Application.dataPath + "/SAVEGAME", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
SaveInfo info = (SaveInfo)formatter.Deserialize(stream);
stream.Close();
markerSprite.GetComponent<SpriteRenderer>().sprite = goOut;
markerSprite.transform.Translate(new Vector3(0, -0.75F, 0));
marker.transform.position = new Vector3(info.posX, info.posY, 0);
Debug.Log(info.fuel);
circle.transform.localScale = new Vector3(info.fuel, info.fuel, 1);
number = 499;
music.enabled = false;
loading.SetActive(true);
notLoading.SetActive(false);
Load();
}
else
{
markerSprite.GetComponent<SpriteRenderer>().sprite = goIn;
Stream stream = File.Open(Application.dataPath + "/SAVEGAME", FileMode.OpenOrCreate);
BinaryFormatter formatter = new BinaryFormatter();
SaveInfo info = new SaveInfo();
info.fuel = 5;
circle.transform.localScale = new Vector3(info.fuel, info.fuel, 1);
Debug.Log(info.fuel);
formatter.Serialize(stream, info);
stream.Close();
number = 499;
music.enabled = false;
loading.SetActive(true);
notLoading.SetActive(false);
Generate();
}
}
void Generate() //Create new stars. Doesn't work?
{
int maxNumber = number;
Stream stream = File.Open(Application.dataPath + "/SAVEGAME", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
info = (SaveInfo)formatter.Deserialize(stream);
while (number >= 1)
{
newStar = Instantiate(starPrefab, new Vector3(Random.Range(-50, 51), Random.Range(-50, 51), 0), Quaternion.identity);
GameObject star = ClosestStar();
float distance = Vector3.Distance(star.transform.position, newStar.transform.position);
if (distance != 0)
{
newStar.tag = "Star";
StarGeneration();
info.positions.Insert(((maxNumber - number) * 2), newStar.transform.position.x);
info.positions.Insert(((maxNumber - number) * 2) + 1, newStar.transform.position.y);
info.infosInt.Insert((maxNumber - number) * 3, newStar.GetComponent<StarInfo>().type);
info.infosInt.Insert(((maxNumber - number) * 3) + 1, newStar.GetComponent<StarInfo>().imageTypes);
info.infosInt.Insert(((maxNumber - number) * 3) + 2, newStar.GetComponent<StarInfo>().systemRotationZ);
info.infosBool.Insert((maxNumber - number) * 2, newStar.GetComponent<StarInfo>().habitable);
info.infosBool.Insert(((maxNumber - number) * 2) + 1, newStar.GetComponent<StarInfo>().richResources);
List<int> list = new List<int>();
list = newStar.GetComponent<StarInfo>().planetTypes;
info.planets.Insert(maxNumber - number, list);
newStar.GetComponent<StarInfo>().starName = StarName();
while (info.names.Contains(newStar.GetComponent<StarInfo>().starName))
{
Debug.Log("Attemting to re-generate star name");
newStar.GetComponent<StarInfo>().starName = StarName();
}
newStar.GetComponentInChildren<TextMesh>().text = newStar.GetComponent<StarInfo>().starName;
if (newStar.GetComponent<StarInfo>().type == 5 || newStar.GetComponent<StarInfo>().type == 6)
{
newStar.GetComponentInChildren<TextMesh>().gameObject.transform.Translate(new Vector3(0, -0.15F, 0), Space.Self);
}
info.names.Insert(maxNumber - number, newStar.GetComponent<StarInfo>().starName);
number -= 1;
}
else
{
Destroy(newStar);
Debug.Log("Script was trying to generate a star on position of another star, but it failed");
}
}
formatter.Serialize(stream, info);
stream.Close();
music.enabled = true;
loading.SetActive(false);
notLoading.SetActive(true);
Destroy(GetComponent<GalaxyGenerator>());
}
void Load() //Load info about stars. Doesn't work because there is no info?
{
Stream stream = File.Open(Application.dataPath + "/SAVEGAME", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
info = (SaveInfo)formatter.Deserialize(stream);
int maxNumber = number;
while (number >= 1)
{
Debug.Log("Entered while"); //I get it
Debug.Log(info.names[maxNumber - number]); //I don't get it. Error : "ArgumentOutOfRangeException : Argument is out of range. Parameter name : index"
Debug.Log("Info exists"); //I don't get it
newStar = Instantiate(starPrefab, new Vector3(info.positions[(maxNumber - number) * 2], info.positions[((maxNumber - number) * 2) + 1], 0), Quaternion.identity);
newStar.GetComponent<StarInfo>().type = info.infosInt[(maxNumber - number) * 3];
newStar.GetComponent<StarInfo>().imageTypes = info.infosInt[((maxNumber - number) * 3) + 1];
newStar.GetComponent<StarInfo>().systemRotationZ = info.infosInt[((maxNumber - number) * 3) + 2];
newStar.GetComponent<StarInfo>().habitable = info.infosBool[(maxNumber - number) * 2];
newStar.GetComponent<StarInfo>().richResources = info.infosBool[((maxNumber - number) * 2) + 1];
newStar.GetComponent<StarInfo>().planetTypes = info.planets[maxNumber - number];
newStar.GetComponent<StarInfo>().starName = info.names[maxNumber - number];
newStar.GetComponentInChildren<TextMesh>().text = info.names[maxNumber - number];
if (newStar.GetComponent<StarInfo>().type == 5 || newStar.GetComponent<StarInfo>().type == 6)
{
newStar.GetComponentInChildren<TextMesh>().gameObject.transform.Translate(new Vector3(0, -0.15F, 0), Space.Self);
}
newStar.tag = "Star";
number -= 1;
}
stream.Close();
}
string StarName() //Generating new star name. Works
{
List<string> s1 = new List<string>();
List<string> s2 = new List<string>();
string name = null;
s1.Insert(0, "A");
s1.Insert(1, "E");
s1.Insert(2, "Y");
s1.Insert(3, "U");
s1.Insert(4, "O");
s1.Insert(5, "I");
s1.Insert(6, "IO");
s1.Insert(7, "YU");
s1.Insert(8, "EE");
s1.Insert(9, "EA");
s2.Insert(0, "B");
s2.Insert(1, "C");
s2.Insert(2, "D");
s2.Insert(3, "F");
s2.Insert(4, "G");
s2.Insert(5, "H");
s2.Insert(6, "J");
s2.Insert(7, "K");
s2.Insert(8, "L");
s2.Insert(9, "M");
s2.Insert(10, "N");
s2.Insert(11, "P");
s2.Insert(12, "Q");
s2.Insert(13, "R");
s2.Insert(14, "S");
s2.Insert(15, "T");
s2.Insert(16, "V");
s2.Insert(17, "W");
s2.Insert(18, "X");
s2.Insert(19, "Z");
s2.Insert(20, "Y");
s2.Insert(21, "TH");
s2.Insert(22, "PR");
s2.Insert(23, "SS");
s2.Insert(24, "SC");
s2.Insert(25, "CL");
s2.Insert(26, "PH");
s2.Insert(27, "PL");
s2.Insert(28, "CR");
s2.Insert(29, "SH");
s2.Insert(30, "RR");
s2.Insert(31, "GR");
s2.Insert(32, "CH");
name = s1[Random.Range(0, 6)] + s2[Random.Range(0, 33)];
int j = Random.Range(0, 2);
for (int i = 0; i < j; i++)
{
string p = s1[Random.Range(0, 10)] + s2[Random.Range(0, 33)];
name = name + p;
}
name = name + s1[Random.Range(0, 10)] + s2[Random.Range(0, 20)];
int k = Random.Range(0, 4);
if (k != 0)
{
if (k == 1)
{
name = name + s1[Random.Range(0, 6)];
}
else if (k == 2)
{
name = s2[Random.Range(0, 20)] + name;
}
else if (k == 3)
{
name = s2[Random.Range(0, 20)] + name + s1[Random.Range(0, 6)];
}
}
return name;
}
void StarGeneration() //Generating new star info (other than name). Works
{
int chance = Random.Range(1, 101);
int secondRandom;
int thirdRandom = Random.Range(1, 6);
if (chance <= 50)
{
newStar.GetComponent<StarInfo>().type = 1;
secondRandom = Random.Range(0, 2);
if (secondRandom == 1)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
if (thirdRandom == 5)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
else if (chance >= 51 && chance <= 70)
{
newStar.GetComponent<StarInfo>().type = 2;
secondRandom = Random.Range(1, 11);
if (secondRandom <= 7)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
if (thirdRandom >= 4)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
else if (chance >= 71 && chance <= 80)
{
newStar.GetComponent<StarInfo>().type = 3;
secondRandom = Random.Range(1, 11);
if (secondRandom <= 9)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
if (thirdRandom >= 2)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
else if (chance >= 81 && chance <= 85)
{
newStar.GetComponent<StarInfo>().type = 4;
secondRandom = Random.Range(0, 2);
if (secondRandom == 1)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
if (thirdRandom >= 3)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
else if (chance == 86)
{
newStar.GetComponent<StarInfo>().type = 5;
newStar.GetComponent<StarInfo>().habitable = false;
}
else if (chance >= 87 && chance <= 96)
{
newStar.GetComponent<StarInfo>().type = 0;
secondRandom = Random.Range(1, 11);
if (secondRandom >= 3)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
newStar.GetComponent<StarInfo>().richResources = false;
}
else if (chance == 97)
{
newStar.GetComponent<StarInfo>().type = 6;
newStar.GetComponent<StarInfo>().habitable = false;
if (thirdRandom >= 4)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
else if (chance == 98)
{
newStar.GetComponent<StarInfo>().type = 7;
newStar.GetComponent<StarInfo>().habitable = false;
newStar.GetComponent<StarInfo>().richResources = true;
}
else if (chance == 99)
{
newStar.GetComponent<StarInfo>().type = 8;
newStar.GetComponent<StarInfo>().habitable = false;
newStar.GetComponent<StarInfo>().richResources = true;
}
else if (chance == 100)
{
newStar.GetComponent<StarInfo>().type = 9;
newStar.GetComponent<StarInfo>().habitable = false;
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().type = 1;
secondRandom = Random.Range(0, 2);
if (secondRandom == 1)
{
newStar.GetComponent<StarInfo>().habitable = true;
}
else
{
newStar.GetComponent<StarInfo>().habitable = false;
}
if (thirdRandom == 5)
{
newStar.GetComponent<StarInfo>().richResources = true;
}
else
{
newStar.GetComponent<StarInfo>().richResources = false;
}
}
int number = 0;
if (newStar.GetComponent<StarInfo>().type != 9)
{
if (newStar.GetComponent<StarInfo>().type >= 1 && newStar.GetComponent<StarInfo>().type <= 4)
{
int planetsRemained = Random.Range(1, 9);
while (planetsRemained >= 1)
{
if (number <= 1)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(0, 3));
}
else if (number >= 2 && number <= 4)
{
if (newStar.GetComponent<StarInfo>().habitable == true)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(1, 5));
}
else
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(1, 3));
}
}
else if (number >= 5)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(5, 7));
}
number = number + 1;
planetsRemained = planetsRemained - 1;
}
}
else if (newStar.GetComponent<StarInfo>().type == 0)
{
int planetsRemained = Random.Range(0, 6);
while (planetsRemained >= 1)
{
if (number == 0)
{
if (newStar.GetComponent<StarInfo>().habitable == true)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(1, 6));
}
else
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(1, 3));
}
}
else if (number >= 1)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(5, 7));
}
number = number + 1;
planetsRemained = planetsRemained - 1;
}
}
else if (newStar.GetComponent<StarInfo>().type >= 6 && newStar.GetComponent<StarInfo>().type <= 8)
{
int planetsRemained = Random.Range(0, 4);
while (planetsRemained >= 1)
{
newStar.GetComponent<StarInfo>().planetTypes.Insert(number, Random.Range(0, 3));
number = number + 1;
planetsRemained = planetsRemained - 1;
}
}
}
newStar.GetComponent<StarInfo>().imageTypes = Random.Range(1, 6);
newStar.GetComponent<StarInfo>().systemRotationZ = Random.Range(0, 360);
}
}
And here is a script that works :
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine.SceneManagement;
public class StarInfoTransfer : MonoBehaviour {
public static InfoReadyForTransfer info;
public static SaveInfo save;
public GameObject marker, loading;
void Start () {
marker = GameObject.FindGameObjectWithTag("Marker");
info = new InfoReadyForTransfer();
if (File.Exists(Application.dataPath + "/TRANSFER")) //The same script is on other scene. Loading info from file works
{
Stream stream = File.Open(Application.dataPath + "/TRANSFER", FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
info = (InfoReadyForTransfer)formatter.Deserialize(stream);
stream.Close();
this.GetComponent<StarInfo>().planetTypes = info.planetTypes;
this.GetComponent<StarInfo>().type = info.type;
this.GetComponent<StarInfo>().habitable = info.habitable;
this.GetComponent<StarInfo>().richResources = info.richResources;
this.GetComponent<StarInfo>().imageTypes = info.imageTypes;
this.GetComponent<StarInfo>().systemRotationZ = info.rotation;
}
}
void OnMouseDown()
{
float distance = Vector3.Distance(marker.transform.position, this.transform.position); //Distance from player position to star
int distanceInt = (int)distance;
if (distance - distanceInt > 0.5F)
{
distanceInt += 1;
}
Stream stream = File.Open(Application.dataPath + "/SAVEGAME", FileMode.Open); //Main save file. I have no idea if it works
BinaryFormatter formatter = new BinaryFormatter();
save = (SaveInfo)formatter.Deserialize(stream);
if ((distanceInt) <= save.fuel)
{
GameObject camera = GameObject.FindGameObjectWithTag("MainCamera");
camera.GetComponent<CameraController>().enabled = false;
GameObject newLoading = Instantiate(loading);
newLoading.transform.SetParent(GameObject.FindGameObjectWithTag("Canvas").transform);
newLoading.GetComponent<RectTransform>().anchoredPosition = new Vector3(0, 0, 0);
save.fuel = save.fuel - distanceInt;
Debug.Log(save.fuel);
save.posX = transform.position.x;
save.posY = transform.position.y;
formatter.Serialize(stream, save);
stream.Close();
info.planetTypes = this.GetComponent<StarInfo>().planetTypes; //Transfer file. Works
info.type = this.GetComponent<StarInfo>().type;
info.habitable = this.GetComponent<StarInfo>().habitable;
info.richResources = this.GetComponent<StarInfo>().richResources;
info.imageTypes = this.GetComponent<StarInfo>().imageTypes;
info.rotation = this.GetComponent<StarInfo>().systemRotationZ;
Stream streamT = File.Open(Application.dataPath + "/TRANSFER", FileMode.OpenOrCreate);
BinaryFormatter formatterT = new BinaryFormatter();
formatterT.Serialize(streamT, info);
streamT.Close();
SceneManager.LoadScene("StarSystem", LoadSceneMode.Single);
}
else
{
stream.Close();
}
}
}
Please, can somebody tell me what is a difference between these two that causes this weird error or fix it? Also, sorry for my bad English…