Karen
Karen

Reputation: 99

How can I save and load the gameObject that the user creates?

I've implemented all the options that the user can choose to customize a 3D object, as well as adding some GUI buttons to improve my old code and to make usability better. But I'm having some trouble figuring out how to save and load a gameObject.

I've read about serialization and I've seen some people mention PlayerPrefs, but I'm still having trouble understanding how to use that with an object.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;

 public class cubeControls : MonoBehaviour
 {
     // Constants for object rotation
     public float moveSpeed = 80.0F;
     public float turnSpeed = 100.0F;

     // Initial scale of the original cube
     public static Vector3 initscale = Vector3.one;

     // Start is called before the first frame update
     void Start()
     {
     }

     // Update is called once per frame
     void Update()
     {
         // Changing the position of the object

         // Moving the object right
         if (Input.GetKey(KeyCode.D))
         {
             transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
     }

         // Moving the object left
         if (Input.GetKey(KeyCode.A))
         {
             transform.Translate(Vector3.left * moveSpeed * Time.deltaTime);
     }

         // Changing the rotation of the object

         // Rotating the cube to the right
         if (Input.GetKey(KeyCode.RightArrow))
         {
             transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
         }

         // Rotating the cube to the left
         if (Input.GetKey(KeyCode.LeftArrow))
         {
             transform.Rotate(Vector3.down, turnSpeed * Time.deltaTime);
         }

         // Saving the current rendered material
         Renderer rend = GetComponent<Renderer>();

         // Changing the scale of the object

         // Double the size of the cube
         if (Input.GetKeyDown(KeyCode.Alpha2))
         {
             transform.localScale += new Vector3(2F, 2F, 2F);
         }

         // Changing the color via key presses

         if (Input.GetKeyDown(KeyCode.R))
         {
             rend.material.SetColor("_Color", Color.red);
         }
     }

     // To add button elements to the visual interface
     void OnGUI() 
     {
         // Changing to cylinder
         if (GUI.Button(new Rect(50, 90, 100, 40), "Cylinder"))
         {
             GameObject newCylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
             newCylinder.AddComponent<cubeControls>();
             Destroy(gameObject);
         }

         // Saving
         if (GUI.Button(new Rect(700, 330, 50, 30), "Save"))
         {
         }

         // Loading
         if (GUI.Button(new Rect(770, 330, 50, 30), "Load"))
         {
         }
     }
 }

Upvotes: 1

Views: 3196

Answers (1)

killer_mech
killer_mech

Reputation: 1588

You cannot save Gameobjects. Only thing you save is details of the game object. Take for example if you have 3D cube with some particle effects first you save the required values of the cube like Position, Rotation, Scale, Color and other necessary elements(particle emitter values which needs to be change). Even in serialisation you will not be able to save Vector3 as it is a struct and have to write your own serialiser for vectors. Basically in short what you save in values required for your gameobjects to work and other behavioral characteristics which required custom inputs from user/ other system. Think of it as way to rebuild your objects to the state where you left off by saving and loading states of variables which affects your objects.

Unity saves are of two types

1) Player prefs : Using player prefs you will be able to save only one value at a time in the field. Usually one of the three:

  • Float
  • Int
  • String

You usually save tokens and other small values which wont require large files

2) Serialized Game Data : Here you save the large data sets & classes like PlayerInfo, Custom changes to scene in a serialized files.

I believe what you are looking for is the second one. So instead of looking for all the examples and getting confused what you can really start with is saving/loading a cube values(position maybe? or anything which you are modifying at runtime) in a file. And gradually you can shift to serializer.

You can check on this following links to help you further understand.

Reference

Save/Load Data using simple BinaryFormatter

XML serialiser


This save snippet is from simple binary formattor link, which saves integer lists of some types & user score.

[System.Serializable]
public class Save
{
  public List<int> livingTargetPositions = new List<int>();
  public List<int> livingTargetsTypes = new List<int>();

  public int hits = 0;
  public int shots = 0;
}

private Save CreateSaveGameObject()
{
  Save save = new Save();
  int i = 0;
  foreach (GameObject targetGameObject in targets)
  {
    Target target = targetGameObject.GetComponent<Target>();
    if (target.activeRobot != null)
    {
      save.livingTargetPositions.Add(target.position);
      save.livingTargetsTypes.Add((int)target.activeRobot.GetComponent<Robot>().type);
      i++;
    }
  }

  save.hits = hits;
  save.shots = shots;

  return save;
}

public void SaveGame()
{
  // 1
  Save save = CreateSaveGameObject();

  // 2
  BinaryFormatter bf = new BinaryFormatter();
  FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
  bf.Serialize(file, save);
  file.Close();

  // 3
  hits = 0;
  shots = 0;
  shotsText.text = "Shots: " + shots;
  hitsText.text = "Hits: " + hits;

  ClearRobots();
  ClearBullets();
  Debug.Log("Game Saved");
}

Upvotes: 1

Related Questions