Search Unity

Resolved Scriptable Objects not holding assigned values in built project.

Discussion in 'Editor & General Support' started by MadboyJames, Aug 5, 2022.

  1. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    I have an issue where scriptable objects are not being referenced correctly after I build my project.
    Due to using additive loading and wanting to reference objects between scenes, I am using the RuntimeAnchors used in UnityOpenProjectOne "Chop Chop" developed by Unity Technologies.
    Here is the script:
    Code (CSharp):
    1. public class RuntimeAnchorBase<T> : DescriptionBaseSO
    2. {
    3.     public UnityAction OnAnchorProvided;
    4.     [Header("Debug")]
    5.     public bool isSet = false; // Any script can check if the transform is null before using it, by just checking this bool
    6.     [SerializeField] private T _value;
    7.     public T Value
    8.     {
    9.         get { return _value; }
    10.     }
    11.     public virtual void Provide(T value)
    12.     {
    13.      
    14.         if (value == null)
    15.         {
    16.             Debug.LogError("A null value was provided to the " + this.name + " runtime anchor.");
    17.             return;
    18.         }
    19.      
    20.         _value = value;
    21.         isSet = true;
    22.         if (OnAnchorProvided != null)
    23.             OnAnchorProvided.Invoke();
    24.     }
    25.     public void Unset()
    26.     {
    27.         _value = default(T);
    28.         isSet = false;
    29.     }
    30.     private void OnDisable()
    31.     {
    32.         Unset();
    33.     }
    34. }
    It works fine in editor.
    In build, references break. I can use logs to see that the correct object is provided... but everything that has referenced the SO or is waiting for a provide reads it as isSet is false with a value==null. It almost seems like, during the build, a new instance of the SO is created for each reference.

    If Scriptable objects aren't meant to be used this way... why are they used like so in Unity's official project?

    Is there some setting somewhere I need to set to make this work?

    NOTE: refactoring _value to be static will allow this pattern to work, but I would like to be able to use instances if possible..
     
  2. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    Update, this only happens when the value provided is from an addressable. While I don't have a "fix", I just created a small "addressableRuntimeAnchor" script, which sadly is not a scriptable Object, but it works.

    Code (CSharp):
    1. public class AddressableRuntimeAnchor : MonoBehaviour
    2. {
    3.     protected static Dictionary<string, GameObject> AddressableInstances;
    4.     public string entryName;
    5.  
    6.     private void Awake()
    7.     {
    8.         if(AddressableInstances == null)
    9.             AddressableInstances = new Dictionary<string,GameObject>();
    10.  
    11.         if (!AddressableInstances.ContainsKey(entryName))
    12.             AddressableInstances.Add(entryName, gameObject);
    13.     }
    14.  
    15.  
    16.     public static GameObject GetAnchor(string entryName)
    17.     {
    18.         if (!AddressableInstances.ContainsKey(entryName))
    19.             return null;
    20.  
    21.         return AddressableInstances[entryName];
    22.     }
    23.  
    24.     private void OnDestroy()
    25.     {
    26.         if (!AddressableInstances.ContainsKey(entryName))
    27.             return;
    28.  
    29.         AddressableInstances.Remove(entryName);
    30.     }
    31. }
    Attach this to the object you want to have an anchor of, then reference it in script with
    Code (CSharp):
    1. GameObject myObjVar = AddressableRuntimeAnchor.GetAnchor("ENTRY_NAME");
    It should be fairly simple to refactor to store non-gameobject types.
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    Are you making sure your SO's are also being built into your addressables groups?
     
  4. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    I was not. The SOs were non-addressable assets. For an experiment, I added the player runtime anchor SO as an addressable, but I still faced the same issue.

    Out of curiosity, is it bad practice to use a hybrid addressable approach? I am making most prefabs addressable, but leaving shaders, textures, SOs, and Scenes as regular assets.
     
  5. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    okay, so I am learning things today. the issue I encountered is likely described in this video at timestamp 5:00
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    Yes that's what I was getting at with my response. If your SO's aren't Addressable as well, then they most likely get duplicated and often lose data. This also makes using SO's as a means to transmit data between scenes fall apart as well.

    You don't have to load them via addressables, they just have to be built into your groups.
     
  7. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    Huh, that's really good to know. What all needs to be loaded and what can just be build? I image that most textures, shaders, materials, meshes and other similar resources just need to be built into the groups?
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    Well you just load what you need and everything that's referenced by it will be loaded alongside it. Idea being that all this referenced content is also built into your groups, of which is handled by addressables.

    In most cases this is just scenes. Then all the art assets, scriptable objects and what not that are referenced get loaded from your groups alongside the scene.

    I'm never actually 'loading' scriptable objects via adressable references. They just have their own groups and are referenced by other objects also built into my addressables groups.

    Hope that makes sense.
     
  9. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    Okay, so there were two issues: the first is I needed to add the png textures to the addressable group. The second was that I needed to remove the underscores from the png filename.