How do I save and load a gameObject that the user creates?

I’ve managed to figure out how to implement all the features/options that I want the user to be able to customize and I also added two buttons on the screen that the user can click to save and load the object. But I’m having some trouble figuring out how to save and load the gameObject itself; I’ve read some posts about serialization for an entire game, but it looks a bit complicated relative to what my professor has gone over in class. Is serialization the only way to do it or is there a simpler method?

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()
    {
        Debug.Log("I am alive!");
    }

    // 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
        * 
        */

        // Reset the rotation to original by returning a rotation at (0, 0, 0)
        if (Input.GetKey(KeyCode.Alpha0))
        {
            transform.rotation = Quaternion.Euler(Vector3.zero);
        }

        // 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
        * 
        */

        // Reset the cube to the original scaled size
        if (Input.GetKeyDown(KeyCode.Alpha0))
        {
            transform.localScale = initscale;
        }

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

        /* Changing the color via key presses
         * 
         */

        // Reset color of cube to original
        if (Input.GetKeyDown(KeyCode.Alpha0))
        {
            rend.material.SetColor("_Color", Color.white);
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            rend.material.SetColor("_Color", Color.red);
        }
    }

    // To add button elements to the visual interface
    void OnGUI() 
    {
        /* Changing the shape of the object
         * 
         */

        // Reset shape to cube
        if (GUI.Button(new Rect(50, 30, 100, 40), "Cube"))
        {
            GameObject newCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            newCube.AddComponent<cubeControls>();
            Destroy(gameObject);
        }

        // 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"))
        {
        }
    }
}

Hi,

Serialization is probably the best way. You only need to tell the compiler which data it should be able to store by flagging it accordingly. This and this tutorial give a good explanation, and the first one briefly touches upon saving per JSON.

A third option would be to write your own binary converter, but that would simply reinvent the wheel.

You could also simply write a description of your object into a .txt file . For example something like “Cube x:1.5 y:2.1 sx:0.5 sy:0.1”. It would be human readable and simpler to debug, but it will take up more storage and it is kinda hacked. You would also have to write a reader and writer for every info that you want to store.

Personally, I’d recommend Serialization, as you’d only need to flag the attribute with “[SerializeField]”, or a whole class with “[System.Serializable]”.

Side note: You cannot directly store Vector3 or Transforms with Serializable. You would need to create auto conversions like this.

Try this script

    private const string KEY_POS_X= "KEY_POSX";
     private const string KEY_POS_Y = "KEY_POSY";
     private const string KEY_POS_Z = "KEY_POS_Z";
     private const string KEY_ROT_X = "KEY_ROT_X";
     private const string KEY_ROT_Y = "KEY_ROT_Y";
     private const string KEY_ROT_Z = "KEY_ROT_Z";
     private const string KEY_ROT_W = "KEY_ROT_W";
     private const string KEY_MOVESPEED = "KEY_MOVESPEED";
     private const string KEY_TURNSPEED = "KEY_TURNSPEED";
     private const string KEY_COLOR_A = "KEY_COLOR_A";
     private const string KEY_COLOR_B = "KEY_COLOR_B";
     private const string KEY_COLOR_G = "KEY_COLOR_G";
     private const string KEY_COLOR_R = "KEY_COLOR_R";
     private const string KEY_LOCSCALE_X = "KEY_LOCSCALE_X";
     private const string KEY_LOCSCALE_Y = "KEY_LOCSCALE_Y";
     private const string KEY_LOCSCALE_Z = "KEY_LOCSCALE_Z";
     private const string KEY_IS_SAVED = "KEY_IS_SAVED";

     public float moveSpeed = 80.0F;
     public float turnSpeed = 100.0F;

     void Start()
     {
          Debug.Log("I am alive!");
     }

     private void Update()
     {
          //your update codes
     }

     private void OnGUI()
     {
          // Saving
          if (GUI.Button(new Rect(700, 330, 50, 30), "Save"))
          {
               PlayerPrefs.SetFloat(KEY_POS_X, transform.position.x);
               PlayerPrefs.SetFloat(KEY_POS_Y, transform.position.y);
               PlayerPrefs.SetFloat(KEY_POS_Z, transform.position.z);
               PlayerPrefs.SetFloat(KEY_ROT_X,transform.rotation.x);
               PlayerPrefs.SetFloat(KEY_ROT_Y, transform.rotation.y);
               PlayerPrefs.SetFloat(KEY_ROT_Z, transform.rotation.z);
               PlayerPrefs.SetFloat(KEY_ROT_W, transform.rotation.w);
               PlayerPrefs.SetFloat(KEY_MOVESPEED,moveSpeed);
               PlayerPrefs.SetFloat(KEY_TURNSPEED,turnSpeed);
               Color color = GetComponent<Renderer>().material.GetColor("_Color");
               PlayerPrefs.SetFloat(KEY_COLOR_A, color.a);
               PlayerPrefs.SetFloat(KEY_COLOR_B,color.b);
               PlayerPrefs.SetFloat(KEY_COLOR_G,color.g);
               PlayerPrefs.SetFloat(KEY_COLOR_R,color.r);
               PlayerPrefs.SetFloat(KEY_LOCSCALE_X,transform.localScale.x);
               PlayerPrefs.SetFloat(KEY_LOCSCALE_Y, transform.localScale.y);
               PlayerPrefs.SetFloat(KEY_LOCSCALE_Z, transform.localScale.z);
               PlayerPrefs.SetInt(KEY_IS_SAVED,1);
          }

          // Loading
          if (GUI.Button(new Rect(770, 330, 50, 30), "Load"))
          {
               if (PlayerPrefs.GetInt(KEY_IS_SAVED,0)==1)
               {
                    Vector3 pos = new Vector3(PlayerPrefs.GetFloat(KEY_POS_X),PlayerPrefs.GetFloat(KEY_POS_Y),PlayerPrefs.GetFloat(KEY_POS_Z));         
                    Quaternion rot = new Quaternion(PlayerPrefs.GetFloat(KEY_ROT_X), PlayerPrefs.GetFloat(KEY_ROT_Y), PlayerPrefs.GetFloat(KEY_ROT_Z),PlayerPrefs.GetFloat(KEY_ROT_W));
                    moveSpeed = PlayerPrefs.GetFloat(KEY_MOVESPEED);
                    turnSpeed = PlayerPrefs.GetFloat(KEY_TURNSPEED);
                    Color color = new Color(PlayerPrefs.GetFloat(KEY_COLOR_R), PlayerPrefs.GetFloat(KEY_COLOR_G), PlayerPrefs.GetFloat(KEY_COLOR_B), PlayerPrefs.GetFloat(KEY_COLOR_A));
                    Vector3 locScale = new Vector3(PlayerPrefs.GetFloat(KEY_LOCSCALE_X), PlayerPrefs.GetFloat(KEY_LOCSCALE_Y), PlayerPrefs.GetFloat(KEY_LOCSCALE_Z));
                    transform.position = pos;
                    transform.rotation = rot;
                    GetComponent<Renderer>().material.SetColor("_Color", color);
                    transform.localScale = locScale;
               }
          }

     }