Search Unity

Scriptable Object Loses some values on build

Discussion in 'Editor & General Support' started by CoughE, Jul 21, 2019.

  1. CoughE

    CoughE

    Joined:
    Oct 26, 2015
    Posts:
    39
    Hi all, very weird bug i've encountered today that I am completely stumped on.

    I have a localization system, where I pair a string ID to a string textEnglish, textSpanish etc, so all I have to do in editor is type in the string ID and then depending on the user's language it displays the corresponding string.

    I call these a value pair, and I store them in a list, inside a ScriptableObject. For clutter's sake I have a different ScriptableObject each with their own list, one for UI, one for dialogue etc.

    This all works 100% great in the editor. But when i try to build the game, some of these values are lost. That's right, not all, some. Going through the lists, a valuepair's id or textEnglish or both strings will become empty. Some of them are fine though, seemingly at random.

    Does anyone have any clue why this would be happening? If none of the values got saved clearly I would be serializing something wrong or something. There is alot of editor code for my ScriptableObject, but really only a single list and some simple strings is behind it, most of the code is to format the ids and text nicely in the inspector.
    Code (CSharp):
    1. [System.Serializable]
    2. public class ValuePair
    3. {
    4.     public string id;
    5.     public string textEnglish;
    6.     public string textFrench;
    7.     public string textSpanish;
    8.     public string comments;
    9.  
    10.     public ValuePair() { }
    11.  
    12.     public virtual void CopyValuesFrom(ValuePair other)
    13.     {
    14.         this.id = other.id;
    15.  
    16.         this.textEnglish = other.textEnglish;
    17.         this.textFrench = other.textFrench;
    18.         this.textSpanish = other.textSpanish;
    19.  
    20.         this.comments = other.comments;
    21.     }
    22. }
    Code (CSharp):
    1. [System.Serializable]
    2. public class SheetStoreBase<T> : ScriptableObject where T : ValuePair
    3. {
    4.     [SerializeField]
    5.     public List<T> localizedTexts;
    6.  
    7.     public virtual void AddValuePairing(string id, string text)
    8.     {
    9.         var newValuePair = default(T);
    10.         newValuePair.id = id;
    11.         newValuePair.textEnglish = text;
    12.         localizedTexts.Add(newValuePair);
    13.     }
    14.  
    15.     public virtual T GetValuePairByID(string id)
    16.     {
    17.         return localizedTexts.FirstOrDefault(t => t.id == id);
    18.     }
    19. #if UNITY_EDITOR
    20.     public void UpdateTextByID(string id, string newText)
    21.     {
    22.         var localizedText = GetValuePairByID(id);
    23.         if (localizedText == null)
    24.         {
    25.             Debug.LogWarning($"No Text is associated with id '{id}'");
    26.             return;
    27.         }
    28.         UnityEditor.Undo.RecordObject(this, $"Set Text({id}) -> {newText}");
    29.  
    30.         SetText(localizedText, newText);
    31.         //Set to serialize
    32.         UnityEditor.EditorUtility.SetDirty(this);
    33.     }
    34.  
    35. #endif
    36.     public void SetText(T foo, string newText)
    37.     {
    38.         switch (GlobalRefs.obj.language)
    39.         {
    40.             case GlobalRefs.Language.English:
    41.                 foo.textEnglish = newText;
    42.                 break;
    43.             case GlobalRefs.Language.Spanish:
    44.                 foo.textSpanish = newText;
    45.                 break;
    46.             case GlobalRefs.Language.French:
    47.                 foo.textFrench = newText;
    48.                 break;
    49.         }
    50.     }
    51.  
    52.     public virtual string GetTextByID(string id)
    53.     {
    54.         var localizedText = GetValuePairByID(id);
    55.  
    56.         if (localizedText == null)
    57.         {
    58.             if (Application.isPlaying)
    59.             {
    60.                 Debug.LogWarning($"No ValuePair is associated with id '{id}'");
    61.             }
    62.             return "ERROR";
    63.         }
    64.         string text = "";
    65.  
    66.         switch (GlobalRefs.obj.language)
    67.         {
    68.             case GlobalRefs.Language.English:
    69.                 text = localizedText.textEnglish;
    70.                 break;
    71.             case GlobalRefs.Language.Spanish:
    72.                 text = localizedText.textSpanish;
    73.                 break;
    74.  
    75.             case GlobalRefs.Language.French:
    76.                 text = localizedText.textFrench;
    77.                 break;
    78.         }
    79.  
    80.         return text;
    81.     }
    82.  
    83. }
    Then from SheetStoreBase, I either make a SingleValuePairSpreadsheet which acts as described earlier, or there is a DoubleValuePairSpreadsheet which contains two string values, one id to two values, so an Inventory item can have an id which points both to the name of an item and the description, but that isn't really important, just putting it here for completions sake
    Code (CSharp):
    1. public class SingleValuePairSpreadsheet : SheetStoreBase<ValuePair>
    2. {
    3.     public override void AddValuePairing(string id, string text)
    4.     {
    5.         var newValuePair = new ValuePair();
    6.         newValuePair.id = id;
    7.         newValuePair.textEnglish = text;
    8.         localizedTexts.Add(newValuePair);
    9.     }
    10. }
    I should also mention that these ScriptableObjects are saved in the Resources Folder as well
     
    Last edited: Jul 21, 2019
  2. CoughE

    CoughE

    Joined:
    Oct 26, 2015
    Posts:
    39
    I figured it out.

    Apparently it was the Generic type casting I was doing that threw off Unity's serialization. I assume that the reason there was random values being empty was due to the strings being copied over in memory, something going on lower level.
     
    ZainGamiVision and Songfugel like this.