Scene tab is not convenient to handle a lot variables. What are the alternatives?

I am starting to have many scene variables in my project. Some of them are long lists of objects.
The tab ""Scene’’ where all the scene variables are displayed is really not convenient. Each time I have to scroll for a while, looking for a specific variable.
I thought that I could store my scene variables in C# scripts, and call them in VS, but it is not working.
Here is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.VisualScripting;

[System.Serializable, Inspectable]

public class RuneData : MonoBehaviour
{
[Inspectable]
public int runeID;
[Inspectable]
public string runeName;
[Inspectable]
public int runeValue;
[Inspectable]
public int IDOfRequiredResource0;
[Inspectable]
public int AmountOfRequiredResource0;
[Inspectable]
public int IDOfRequiredResource1;
[Inspectable]
public int AmountOfRequiredResource1;
[Inspectable]
public int IDOfRequiredResource2;
[Inspectable]
public int AmountOfRequiredResource2;
[Inspectable]
public int IDOfRequiredResource3;
[Inspectable]
public int AmountOfRequiredResource3;

public List RuneDataList = new List()
{
//WeatherAltar

new RuneData(){runeID = 0, runeName = “Rain0”, runeValue = 0,
IDOfRequiredResource0 = 0, AmountOfRequiredResource0 = 100,
IDOfRequiredResource1 = -1, AmountOfRequiredResource1 = 0,
IDOfRequiredResource2 = -1, AmountOfRequiredResource2 = 0,
IDOfRequiredResource3 = -1, AmountOfRequiredResource3 = 0},

new RuneData(){runeID = 1, runeName = “Rain1”, runeValue = 1,
IDOfRequiredResource0 = 0, AmountOfRequiredResource0 = 150,
IDOfRequiredResource1 = 1, AmountOfRequiredResource1 = 50,
IDOfRequiredResource2 = -1, AmountOfRequiredResource2 = 0,
IDOfRequiredResource3 = -1, AmountOfRequiredResource3 = 0},

};

But this is not working as you can see in the screenshot.
And also it seems that I have to attach the script to every object that needs to access to this variable.

My real goal is to find a way to handle all my scene variables an efficient way without scrolling. Could you suggest some alternatives?

I am not a programmer, so please provide some details if code is involved.

Thank you!

1 Like

I think this might be useful to you:

https://docs.unity3d.com/Packages/com.unity.visualscripting@1.7/manual/vs-variables-reference.html#variables-api

If you want to use the C# data structures right in the Scene Variables, you can’t inherit from Monobehaviour.

ie something along these lines:

using System;
using System.Collections.Generic;
using Unity.VisualScripting;

[Inspectable, Serializable, IncludeInSettings(true)]
public class RuneData
{
    [Inspectable]
    public List<Rune> RuneDataList = new List<Rune>();
}

[Inspectable, Serializable, IncludeInSettings(true)]
public struct Rune
{
    [Inspectable]
    public int ID;
    [Inspectable]
    public string Name;
    [Inspectable]
    public int Value;
    [Inspectable]
    public List<Resource> RequiredResources;
}
 
[Inspectable, Serializable, IncludeInSettings(true)]
public struct Resource
{
    [Inspectable]
    public int ID;
    [Inspectable]
    public int AmountRequired;
}

You can then do stuff like this:

It doesn’t like nested lists, however:

Needs a custom drawer imlementation for that.

Runes can still be nested in the built in AoTList as a workaround for nested list issue:

2 Likes

Thanks for the link, but it is showing how to access to scene variable from a c# script. While I need the opposite: I’d like to define a variable with its value (var i = 999) somewhere outside the Scene variable tab, and then in VS get i which is 999.

Thanks! It’s actually a better way to define the rune variable. But the issue is still there. How would you handle a list of 100 runes, each one with different resources. It is a very long list displayed in the Scene tab. And this list is just one variable among all the scene variables. So the Scene tab is getting crowded and is not a convenient tools to manage variables.

How would you do in your own project? Would you just live with it, or would you think of some alternative?

I found the answer on this video:

https://www.youtube.com/watch?v=HmrvlRCjR04

And it seems it’s yours :smile:

Typically, I put all this Read Only data that is not changed at runtime in Scriptable Objects.

using System;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

[IncludeInSettings(true)]
[CreateAssetMenu(fileName = "New RuneData", menuName = "New/Create RuneData")]
public class RuneData: ScriptableObject
{
    public List<Rune> Runes = new List<Rune>();
}

[Inspectable, Serializable, IncludeInSettings(true)]
public struct Rune
{
    public int ID;
    public string Name;
    public int Value;
}

With this code, you can right click in Project Window and go to New/Create RuneData which will create a RuneData scriptable object asset. You can then select that scriptable object and add content to Runes list.

You can then do this:

No extra space is taken in the variables window and the scriptable object serves as its own contained library of data. And since it’s an asset, any object can easily reference it.

If there are more than say 20-30 items on a list like that, then I’d typically have a Google Sheet that I export as CSV which is then parsed in Unity and converted to a Scriptable Object.

This is exactly what I was looking for! Thank you so much!
I have 2 more questions:

  • You mentioned that you do this for Read Only variables, but I can see the option to set the values of the elements in the list. Is there a reason to avoid do the same for variables that change in runtime?
  • I am really interested in exporting data in CSV, but I don’t know how to use it in Unity. Do you have a link to some documentation?

You can use scriptable objects for mutable runtime data as well. But I don’t particularly like that because Scriptable Objects are scene independent assets and they retain any changes made in Play mode (and also retain changes made between scene loads assuming both scenes reference the same scriptable object from the same source), which might be desirable in some circumstances but require extra boilerplate to reset them in case you don’t want for that to happen. Scriptable Object event executution order can also be sometimes unpredictable when compared to a regular Monobehavior so I personally prefer SOs for immutable data only.

There are ready-made frameworks for Scriptable Object based variables and events like Scriptable Object Architecture and Unity Atoms.

Those frameworks are based on these talks about Scriptable Object based game architecture:

https://www.youtube.com/watch?v=6vmRwLYWNRo

https://www.youtube.com/watch?v=raQ3iHhE_Kk

It’s a pretty deep rabbit hole if you want to go nuts with scriptable objects.

The parser you write would be specific for your project. Youtube is full of this stuff.

For UVS:

https://www.youtube.com/watch?v=tHJmvgEHvBc

And there are a lot of vids for C# like this:

https://www.youtube.com/watch?v=tI9NEm02EuE

Wow, glad I was able to help after all!

1 Like

Thanks again, very useful!