List doesn't count any values past 25

I have a list. It has 50 (technically 51) values in it.

[HideInInspector] public List<double> upgradeCosts = new() { 0 /* First 0 means nothing, since item 1 counts as "item 0" */, 0, 0.1, 0.2, 0.5, 2, 5, 12, 20, 30, 100 /* 10 */, 125, 200, 450, 750, 900, 1100, 1500, 2500, 9000, 25000 /* 20 */, /* costs past this are subject to change */ 50000, 150000, 250000, 400000, 1e6, 1.5e6, 2.3e6, 2.5e6, 3.25e6, 5e6 /* 30 */, 8e6, 1.4e7, 2e7, 4.4e7, 9e7, 1.1e8, 1.3e8, 2.2e8, 3e8, 5e8 /* 40 */, 9.4e8, 1.5e9, 2.2e9, 3.7e9, 6.2e9, 8e9, 9.8e9, 1.34e10, 2.5e10, 1e11 /* 50 */ };

In another script that references this script, I wrote Debug.Log("Upgrade Costs List: " + USM.upgradeCosts.Count);

No matter how many values I add, the result is always:
image_2025-02-20_150947174

Does anyone know why this is happening? I don’t believe there’s anything else that should be (or could be) limiting it.

I’m assuming this is in a MonoBehaviour script? If so, the reason this is happening is that once the field is serialized by Unity, it will maintain that same serialized value, no matter how much you change its assigned value.

To fix this, you either need to assign a new list with your own values on Awake(), or else add the [NonSerialized] attribute to the field.

2 Likes

Yep, that was it (the On Awake)

I don’t know why this didn’t happen before, as I had 20 set up wayyy before this.

Doesn’t explain why it only showed 25 and not 20 though.

Thanks!

You’re welcome! The serialized value is saved the first time you save the prefab / scene that the script is present in, so most likely in your case this was when the list had 25 entries.

1 Like

^ ^ ^ This is an extremely common thing to run into in Unity, and here is the reasons behind it as well as a discussion about how to “play nice” when working with serialized data:

Serialized / public fields in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

  • what the class constructor makes (either default(T) or else field initializers, eg “what’s in your code”)

  • what may be saved with the prefab

  • what may be saved with the prefab override(s)/variant(s)

  • what may be saved in the scene and not applied to the prefab

  • what may be changed in the scene and not yet saved to disk

  • what may be changed in OnEnable(), Awake(), Start(), or even later

Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

Here’s the official discussion: Serialization in Unity

If you must initialize fields, then do so in the void Reset() method, which ONLY runs in the UnityEditor.

Here’s more nitty-gritty on serialization:

Field initializers versus using Reset() function and Unity serialization:

To avoid complexity in your prefabs / scenes, I recommend NEVER using the FormerlySerializedAsAttribute

Combining [HideInInspector] with public or SerializeField is kinda dangerous as the values are serialized but not visible and therefore not editable. This combination only makes sense when you have other means to edit the values (some kind of custom input / editor). In cases where you don’t want a public field to be serialized, just use the NonSerialized attribute. Fields that are not serialized are automatically not visible in the inspector as the inspector can only show variables that are serializable.

1 Like