- Home /
Complicated save problem
Alright, I have a terribly difficult problem for you guys out there (either that, or I'm a simple person :P):
So I have a saving system set up for my game that, so far, saves the player's exact position as well as a variable labeled "houseProgress" that essentially makes sure the game progress through its story:
Script that saves:
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class GameControl : MonoBehaviour {
public static GameControl control;
public GameObject player;
public Vector3 pos;
public float houseProgress;
public PlayerActivate playerActivateScript;
void Awake(){
player = GameObject.FindGameObjectWithTag ("Player");
playerActivateScript = player.GetComponent<PlayerActivate> ();
if (control == null) {
DontDestroyOnLoad (gameObject);
control = this;
} else if (control != this) {
Destroy (gameObject);
}
}
void Update(){
if (player == null) {
player = GameObject.FindGameObjectWithTag ("Player");
playerActivateScript = player.GetComponent<PlayerActivate> ();
}
}
public void Save()
{
//playerPosition
PlayerPrefs.SetFloat ("x", player.transform.position.x);
PlayerPrefs.SetFloat ("y", player.transform.position.y);
PlayerPrefs.SetFloat ("z", player.transform.position.z);
PlayerPrefs.SetFloat ("houseProgress", playerActivateScript.houseProgress);
}
public void Load()
{
player.transform.position = new Vector3 (PlayerPrefs.GetFloat ("x"), PlayerPrefs.GetFloat ("y"), PlayerPrefs.GetFloat ("z"));
}
}
This script does alright when it comes to saving the player's position. The only problem is that, when the scene changes (which always happens alongside the save script), I get a TON of null reference errors in some scenes, and for good reason because the player object does not exist in some scenes I have set up, so hopefully someone can help me deal with this problem.
So that's the first problem, the second regarding the save script is the houseProgress variable. It is a float that increases by one every time the player does something. However, it doesn't seem to want to save what it is at. Here is the script I have set up so far that affects it:
if (check.isColliding == true) {
houseProgress += 1;
GameControl.control.Save ();
SceneManager.LoadScene ("Journal Entry 1");
}
I think I know the problem may lie with the variable is tied to the player, which isn't in the Journal Entry scene, so it resets back to the value of 0, so I want to know how I can make this persist.
And that is it! If anyone needs ANY information, please let me know!
Answer by TBruce · May 02, 2016 at 06:25 PM
Start with this, it should at least correct all your errors
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class GameControl : MonoBehaviour
{
public static GameControl control;
public GameObject player;
public Vector3 pos;
public float houseProgress;
public PlayerActivate playerActivateScript;
void Awake()
{
UpdatePlaerInfo();
if (control == null)
{
DontDestroyOnLoad (gameObject);
control = this;
} else if (control != this)
{
Destroy (gameObject);
}
}
void Update()
{
UpdatePlaerInfo();
}
void UpdatePlaerInfo()
{
if (player == null)
{
player = GameObject.FindGameObjectWithTag ("Player");
}
if ((player != null) && (playerActivateScript == null)))
{
playerActivateScript = player.GetComponent<PlayerActivate> ();
}
}
public void Save()
{
//playerPosition
if (player != null)
{
PlayerPrefs.SetFloat ("x", player.transform.position.x);
PlayerPrefs.SetFloat ("y", player.transform.position.y);
PlayerPrefs.SetFloat ("z", player.transform.position.z);
}
if (playerActivateScript != null)
{
PlayerPrefs.SetFloat ("houseProgress", playerActivateScript.houseProgress);
}
}
public void Load()
{
if ((player != null) &&
(PlayerPrefs.GetKey("x") != null) &&
(PlayerPrefs.GetKey("y") != null) &&
(PlayerPrefs.GetKey("z") != null))
{
player.transform.position = new Vector3 (PlayerPrefs.GetFloat ("x"), PlayerPrefs.GetFloat ("y"), PlayerPrefs.GetFloat ("z"));
}
}
}
yeah, but it won't probably save anything for as long as everything is null at call time.
I am happy that you could get it working.
Edit: I would also like to add that calling UpdatePlaerInfo() in the Update function could substantially have an effect on performance. If you have not already considered this you may want to do this at intervals.
Yeah, I'm very much aware of that. Strangely though, it doesn't seem to be having a ton of performance problems when play testing. Nonetheless, I'll make sure I take care of that.
Answer by Outliver · May 02, 2016 at 06:27 PM
I don't quite get you point. You're already giving the answers in your own very question.
First, make sure, you save the settings BEFORE loading a new scene.
Second, objects are always treated as references. Therefore, when you load your new scene without the player object, your playerActiveScript gets nulled. You would therefore need to do another GetComponent() call.
After reading this, I decided to go back and figure out if I overlooked anything, because whenever I get replies like these, I know for a FACT that I did.
Sure enough, I did.
You see, my first problem was pretty easy to fix, and I wish I could accept two answers because the other guy did indeed help me get rid of all of those errors showing up when I was in a scene without a player object.
As for my second problem, I found out that I needed to use that PlayerUpdateInfo function in the load function (which is where the problem was actually taking place) so that, when a load is called, the player object could be found while the load was executing, which it wasn't earlier, thus the houseProgress variable wasn't loading. :/
True heroes never get the pay-off ;) Glad, I could help and that you got your problem solved :)