What is it that makes the array elements appear in the SO YAML

Hi I created my own SO(scriptable object) for experience:

   [CreateAssetMenu(fileName = "ExperienceToLevel", menuName = "Attributes/Experience To Level", order = 0)]
    public class ExperienceToLevel : ScriptableObject
    {
        public int[] XPRequiredArray;
    }

The Progression SO in YAML shows all of the elements for the arrays as shown in the video but the numbers aren’t shown for my own SO.

What is missing/ needs changing for the numbers/elements to appear in YAML?

It might be that the project hasn’t been saved yet. Pretty much all changes to SO aren’t actually written to disk until you Save Project. It looks like they’re saved to disk, because after all, they’re right there in the project window, right? Nope, not till you Save Project.

That makes sense however in this case it was already saved and I’ve just tried again today to make sure and it still isn’t showing the elements.

Then I’m not at all sure what’s going on, as that’s how Unity stores the information.
Out of curiousity, paste in your SO’s inspector, and the text of the YAML.

The YAML for the SO:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: d200e0a0adca934449a40a9d6ee183ca, type: 3}
  m_Name: ExperienceToLevel
  m_EditorClassIdentifier: 
  XPRequiredArray: 32000000960000002c010000c201000058020000

image

Now that’s interesting. I’m not sure if that’s a bitpacked array or if they’ve stuffed the array in the database. I’m going to have to research this further.

I’m away from my coding computer atm… as an experiment… try changing the array definition to this:

[System.Serializable]
struct Test
{
    public int[] XPRequiredArray;
}
[SerializeField] Test test;

You will probably have to type in the data again, but this is for science.

1 Like

Well if its for science, then I have to do it :grinning_face_with_smiling_eyes:

Just to make sure I got all of the code correct:

    [CreateAssetMenu(fileName = "ExperienceToLevel", menuName = "Attributes/Experience To Level", order = 0)]
    public class ExperienceToLevel : ScriptableObject
    {
        [System.Serializable]
        public struct Test
        {
            public int[] XPRequiredArray;
        }

        [SerializeField] Test _test;
    }

In YAML it appears like:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: d200e0a0adca934449a40a9d6ee183ca, type: 3}
  m_Name: ExperienceToLevel
  m_EditorClassIdentifier: 
  XPRequiredArray: 32000000960000002c010000c201000058020000

So unfortunately I don’t think it worked.

Actually… it almost doesn’t look like you made the change… Did you save the Project after editing the script and SO?

So here’s what’s going on:

When Unity stores a array of ints, it packs them into a long string.
I tried six ways from Tuesday to get the YAML to break them out, but it packed it no matter what I did… and in a way it makes perfect sense… when I put in 1, 2, 3, 4, 5 as the elements, the resulting value was

ints: 0100000002000000030000000400000005000000

So here’s what I did to get these results:

using UnityEngine;

[CreateAssetMenu(fileName = "TestArray", menuName = "Test Array")]
public class ScriptableArray : ScriptableObject
{
    [SerializeField] private int[] ints;
    [SerializeField] float[] floats;
}

resulted in

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 1e1ce10ae35905446b35c99add50d25b, type: 3}
  m_Name: TestArray
  m_EditorClassIdentifier: 
  ints: 0100000002000000030000000400000005000000
  floats:
  - 1
  - 2
  - 3
  - 4
  - 5

With some further testing, playing around with the values, the ints are packed as LittleEndian Hexadecimal numbers… so, for example, 169 becomes a9000000 and 256 becomes 00010000.
(Little Endian is where the least significant byte is put first and the most significant byte is last). A packed int string then would simply have to divide the number of characters in the string by 8 and unpack each one as a value by converting them from a hex string to an int.

1 Like

Thanks for the thorough research this is very useful information, although I don’t fully understand the hexadecimal information you’ve provided(Ill have to do further research) but from what I’ve gathered it’s much easier to work with floats?

So it might be worth using floats even though I won’t be using decimal values and then casting them into an int after?

Yeah, if you’re planning on editing the YAML, it’s infinitely easier to deal with the floats than the packed hexadecimals. Hexadecimal - Wikipedia

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms