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 shepsaus000 · Apr 19, 2016 at 06:16 PM · scripting problempositionscripting beginnersaveload

Having terrible trouble with saving/loading player position

So I've looked at the beginner tutorial for how to save and load small bits of information using player prefs, but my problem is a little unique, in that I want my player's exact position saved when they perform a certain action in game, and it only loads when the player dies. I know that there are other questions like this that have been answered, but I couldn't make much sense out of the answers, either because it was in javascript, or it was done in a way that requires more in depth knowledge on the subject.

So, I was wondering if you guys could help me by taking a look at these few excerpts of my scripts and tell me what I need to do to save my player's position, and what do I need to do to load it back up.

This is the script that contains data:

 using aUnityEngine;
 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;
 
 
     void Awake(){
         if (control == null) {
             DontDestroyOnLoad (gameObject);
             control = this;
         } else if (control != this) {
             Destroy (gameObject);
         }
 
     }
     public void Save()
     {
         BinaryFormatter bf = new BinaryFormatter ();
         FileStream file = File.Create (Application.persistentDataPath + "/playerInfo.dat");
 
         PlayerData data = new PlayerData ();
         data.player = player;
 
         bf.Serialize (file, data);
         file.Close();
     }
 
     public void Load()
     {
         if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
             BinaryFormatter bf = new BinaryFormatter ();
             FileStream file = File.Open (Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
             PlayerData data = (PlayerData)bf.Deserialize (file);
             file.Close ();
             player = data.player;
         }
             
     }
 
 }
 
 [Serializable]
 class PlayerData
 {
     public GameObject player;
 }



This is the script that causes a save to occur:

 void Update () {
 
         //chestclick
         ray = Camera.main.ScreenPointToRay (Input.mousePosition);
         if (Physics.Raycast (ray, out hit)) {
             if (Input.GetButtonDown ("Fire1")) {
                 if (hit.transform.name == "Chest") {
                     GameControl.control.Save();
                 }
             }
         }



And this is the script that loads the data:

 void OnTriggerEnter(Collider other)
     {
              if (other.gameObject.CompareTag ("Player")) {
             GameControl.control.Load();
         }
 }
 


Keep in mind that everything seems to be set up correctly, for I am getting no errors, save for when the save/load parts of the scripts activate.

Comment
Add comment · Show 1
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 incorrect · Apr 19, 2016 at 06:25 PM 0
Share

Have you tried figuring out what parts of code are actually executed? You can paste some Debug.Log("Chest was hit"); like lines to check it.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Immanuel-Scholz · Apr 20, 2016 at 07:46 AM

You are serializing a simple data class "PlayerData" using C#'s builtin BinaryFormatter. That is fine - in theory.

However, you can not serialze a GameObject reference there. GameObject is an unity class, mostly implemented in C++. You can not directly try to serialize such a complex class. In the very best, you will serialize all C# parts of the player reference (such as internal pointer and handles used by C++) and it might restore the reference to the original object (but only the reference, not the actual values of that object).

In the worst case, it will simply crash because the said handles and internal pointers are not valid anymore.

So what can you serialize using BinaryFormatter? Basically all standard C# datas and some very simple structs that also need to be declared [Serializable]. Not even Unity-structs like a Matrix3x3 or a Vector3 is serializable with BinaryFormatter.

Edit: After some comments, the easiest way is to abandon BinaryFormatter and use JsonUtility that ships since Unity 5.3. This tool can convert any unity-serializable object properties into JSON text format and back. The code example has been updated accordingly. Note, that JsonUtility still can not serialize complex Unity-intern things like a whole GameObject. But it can serialize basic structs like Vector3, Quaternion, Color etc.. (It also can serialize self-made MonoBehaviours, although you need to use AddComponent + FromJsonOverwrite to deserialize these)

First, think about what exactly it is you want to restore? What can change of the player that should be reset? You wrote already that you like to save/restore the players position. Also its rotation? Can the scale change?

Then just set/read these exact primitive values from PlayerData.

  public void Save()
  {
      PlayerData data = new PlayerData ();
      data.playerPosition = player.transform.position;
      data.playerRotation = player.transform.rotation;
      string json = JsonUtility.ToJson(data);
      File.WriteAllText(Application.persistentDataPath + "/playerInfo.dat", json);
  }
 
  public void Load()
  {
      string json = File.ReadAllText(Application.persistentDataPath + "/playerInfo.dat");
      PlayerData data = JsonUtility.FromJson<PlayerData>(json);
      player = data.player;
      player.transform.position = data.playerPosition;
      player.transform.rotation = data.playerRotation;
  }
 
  [Serializable]
  class PlayerData
  {
      public Vector playerPosition;
      public Quaternion playerRotation;
  }

Of course, the variable "player" needs to be ready and set up correctly in Load before you read out the serialized values. Whether you can just reuse the currently deceased player or you have to completely recreate him is up to you to decide (in the latter, you might think about spawning the player out of some prefab when the game starts too - just to keep things consistent).

Comment
Add comment · Show 5 · 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 shepsaus000 · Apr 20, 2016 at 03:27 PM 0
Share

Sorry for the delay in responding!

Alright, so I understand what you're getting at. You're basically saying that a BinaryFormatter can't quite save what I was wanting it to save, which makes sense because it seems like its meant for simple data rather than entire GameObjects. So, I decided to copy down what you had which is basically the player GameObject, but broken down into data that can be saved, and from the looks of it, this script will work when executed correctly...

unfortunately, my beginning understanding for this topic makes it difficult to figure out what to do with this new error I'm getting.

So, I decided to turn that Vector in the private serializable PlayerData class into a Vector3, for this game is in 3D, but whenever the Save function executes in-game, I get an error saying that it isn't marked as serializable. So, I decided to follow what you put down (Vector) and I get a compiler error saying that the type couldn't be found.

Also, I had a problem understanding what you meant by having the variable player set up.

Perhaps you can shine some light on this?

avatar image Immanuel-Scholz shepsaus000 · Apr 20, 2016 at 03:33 PM 0
Share

Indeed, seems like even the builtin data structs of Unity can not be used with BinaryFormatter.

You could now press on and put the individual members of the structs there (float playerPositionX, float playerPositionY ...) but this gets ugly very quickly.

Another way which might be a lot easier would be JsonUtility.ToJson and .FromJson which converts any Unity-serializable data structure to/from JSON text. You get a plain string out this way, so you might want to use File.WriteAllText / File.ReadAllText ins$$anonymous$$d.

Or you could just dump the string into PlayerPrefs, then your code does not even need a file system (and will run on more platforms, e.g. on WebGL)

avatar image shepsaus000 Immanuel-Scholz · Apr 20, 2016 at 04:26 PM 0
Share

Can you elaborate on this JSON text thing that you mentioned? I have never heard of this thing ever since I've started scripting and it sounds like it would make my life immensely easy, especially since I don't only plan on saving my player's position, but other objects' positions as well (along with whether or not they exist in the scene).

Show more comments
avatar image
0

Answer by CubeCrafter360 · Apr 30, 2017 at 04:34 PM

Dude where you + the data path i learned that you should not use + but use , instead

soo instead off string json = File.ReadAllText(Application.persistentDataPath + "/playerInfo.dat"); do string json = File.ReadAllText(Application.persistentDataPath ,"/playerInfo.dat");

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

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

50 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 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 teleport game object to another scene at the exact position from previous scene? 0 Answers

randomly Instantiate items 0 Answers

Help with double jump script! 2 Answers

My movement script wont work 1 Answer

Issues using two scripts. 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