Class not showing in inspector, even as public or marked serializable

Hello,

I’m currently deep in making a saving system that can save procedurally spawned gameobjects. I’ve read that serializing a class that derives from Monobehaviour isn’t a good idea, so I’ve thought of this solution:

using System.Collections;
using UnityEngine;

//manages stuff like cutting trees
public class TreeScript : MonoBehaviour{
    TreeScriptValues TSV = new TreeScriptValues();
    // Update is called once per frame
    void FixedUpdate ()
    {
        if (TSV.TreeFalling)
        {
            TSV.Rigid.AddForce(TSV.FallDirection * TSV.Force);
            if (TSV.TopOfTree.position.y <= TSV.TopOfTreeToGroundDistance)
            {
                TSV.TreeFalling = false;
                transform.tag = "CutTree";
                TSV.Rigid.isKinematic = true;
                Debug.Log(gameObject.name + " was cut down!");
            }
        }
    }

    public void TreeFall()
    {
        if (!TSV.TreeFalling)
        {
            TSV.Rigid.isKinematic = false;
            TSV.FallDirection = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f));
            TSV.TreeFalling = true;
            //StartCoroutine(FallTimer());
        }
    }
}

//stores values that can be serialized in the saving process later
[System.Serializable]
public class TreeScriptValues
{
    public string Name;
    public string RewardName;
    public float RewardAmount;
    public float TotalCutTime;
    public float SoFarCutTime;
    public Rigidbody Rigid;
    public Transform Player;
    public Transform TopOfTree;
    public Vector3 FallDirection;
    public float Force;
    public bool TreeFalling;
    public float TopOfTreeToGroundDistance;
}

Basically, I’m keeping all variables in a separate class that I can serialize later. However, this class (TreeScriptValues) is not showing up in the Inspector. I’m not sure what I’m doing wrong.

Any ideas?

Thank you!

In TreeScript, make the variable have a [SerializeField] attribute, or make it public so it shows up, I think?

2 Likes

This line:

TreeScriptValues TSV = new TreeScriptValues();

C# classes default fields as private. This means this is a private field.

Private fields are not serialized by unity unless explicitly attributed as such.

As @methos5k says, either stick the ‘SerializeField’ attribute on it, or mark it public.

2 Likes

Worth noting that if your goal is saving things to a disk, then having a UnityEngine.Object-derived type (I see Transforms and a Rigidbody) in your save data class is going to be all sorts of awkward to deal with. Ideally you should only be saving the data necessary to reconstruct the object from a given starting point, not “all of the data”.

In a situation like this, you might want to use a prefab in order to maintain links between components in the same GO hierarchy (have a “default tree object” prefab), while using the save data to just fill in bits and pieces where they’re needed as you instantiate them. I would put the UnityEngine.Object references in the main MonoBehaviour class instead.

If your goal is to be able to recreate an entire arbitrary GO hierarchy using only your own serialized data, things are probably going to get really complicated. The “StateTokens” in @lordofduct 's Spacepuppy Framework might be a good thing to look at for an idea of how to pull that off with a little work, assuming he kept them in the 3.0 update.

2 Likes

Thanks! That worked; I didn’t realize that the line you highlighted would affect the Inspector’s display of the TreeScriptValues class.

I’ll elaborate on that. I’m creating a world where as you walk, “tiles” of ground spawn around you. Each tile has objects (simply spawned prefabs) on it (trees, enemies etc…) that you can interact with. Therefore, I need to save the objects on the tiles and have a way to reload them. This has had me in a corner for a while. I’m now trying to save the object positions and the values of the scripts that are intractable and load them at the start of the game. At the start of the game, I want to instantiate the prefabs, then replace the values with the saved ones.

So I probably should remove Transform Player and Transform TopOfTree since those don’t need to be saved.

Time will tell how successful I am :confused:

StateToken still exists, it’s in my SPTween module:
https://github.com/lordofduct/spacepuppy-unity-framework-3.0/blob/master/SPTween/Dynamic/StateToken.cs

I never really used it for serializing the state of a Transform or anything like that. I always used it for tweening (like say I have a waypoint path for a camera to go through, and as it hits each node in the path, I modify the camera’s properties. I use StateToken to facilitate this).

I guess it could be repurposed for that use. Of course it’d have to be marked serializable (which I just added right now, though I’m only supporting my serialization engine or the built in BinaryFormatter, and not the unity one, since it uses a dictionary and I hate how unity implements that).

Speaking of my serialization library, I’m planning on adding a feature to serialize a unity object structure (GameObject’s and what not). Currently I only implement a way to lookup prefabs by id an repopulate via that. But adding a structural serialization could be very useful in some future projects that may have crafting like gameplay elements.