Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[v0.6.7] Scriptable Object reference is a new instance

Discussion in 'Addressables' started by MaskedMouse, Mar 9, 2019.

  1. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    I have a bootstrap scene which loads essential data into a Scriptable Object using json.
    The loader is using a direct reference to the Scriptable Object from the project.

    One of my addressable assets reference that same Scriptable Object, but when that asset is loaded, the instance of the scriptable object is not the same. The data for that asset is not the same.

    I can't seem to share the data from the same Scriptable Object when one is a normal asset and the other is an addressable asset referencing the same Scriptable Object. The addressable asset is creating a new instance of the Scriptable Object.

    If I understand correctly what is happening, the normal asset that is in the scene is using a baked instance of the scriptable object. The Addressable Asset that is loaded into the scene is using an Asset Bundle instance of the scriptable object because it is a dependency? Or is it a bug?

    Not quite what I wanted as behaviour, sadly it doesn't inject the baked instance of the scriptable object.
    Not sure how to continue with that other than loading in that scriptable object everywhere using Addressables to keep the same instance. But then I have to make several script changes everytime and everywhere where the scriptable object is used once it is moved to addressable assets. Which is quite a bother and unintuitive.

    Not sure what to do next to fix my problem, does anyone have any suggestions?
     
    LeleUnity and Rafarel like this.
  2. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Anything pulled into the build due to being referenced by a scene that's in the build will not point to an asset bundle. If it's something like a scriptable object, it's pulled into the scene. If it's something like a texture, then it's still separate, but essentially a copy is made. So the version that Addressables is loading is the actual file in the bundle that addressables builds. The version your scene is loading is the copy pulled into the scene. There is no re-linking them.

    My suggestion is to have your bootstrap scene use an AssetReference instead of a direct reference. then you should be able to reference the same data in multiple places.
     
    Rafarel likes this.
  3. gtamrLailroe

    gtamrLailroe

    Joined:
    Nov 10, 2017
    Posts:
    2
    I think ScriptableObject must be stay ScriptableObject(single instance), or we lose all advantage of ScriptableObject
     
  4. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Theres no re-linking the ScriptableObjects which is kind of something I expected to be the case.
    It is either keep everything local or get everything addressable

    In my case I made a static class with scriptable object variables and initializing them in the bootstrap scene.
    Then reference to the static class in any script further on. (which kind of beats the purpose of scriptable object in the first place)

    Another solution what could've worked is getting everything into addressables. If everything is addressable then it will always load the addressable version of the Scriptable Object. That way everything can be updated too (Except scripts of course) by just building new addressables. In my case that would be good since WebGL is so slow to build (about 5 minutes) in comparison to something like ThreeJS (a few seconds), but thats due to Unity converting from C# to C++ to WebAssembly, it just takes long.
     
    Last edited: Mar 13, 2019
    Colin_MacLeod, Rafarel and unity_bill like this.
  5. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Hi @MaskedMouse,

    I think I have the same kind of issue that you have.

    I described my issue and my tests here :
    https://forum.unity.com/threads/scriptableobject-asset-and-addressables.652525/

    Can you tell me if you have same issues, conclusions ?
    Did you make any progress on this, what is the strategy ?
    I'll try to put my scene as addressable to see if it fixes the reference.
    Totally!
     
  6. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    I almost came to the conclusion that all your assets HAVE to be addressable to avoid this issue including your scenes.
    All my test scenes are addressable + some prefabs and they can share data with a scriptable object without loosing link ... The only thing that is not addressable is the Bootstrap scene that takes care of loading the first scene via Addressable.LoadScene

    Is that the way of working with addressable?
    Can you confirm this @unity_bill please?
     
  7. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Yeah that's the same conclusion. As Bill explained, when you have an asset reference of the scriptable object in scene it will be included in the build. Any addressable asset that references that same scriptable object will have it included in the addressable asset bundles. Which means that there are 2 separate versions of that same scriptable object data. One in the scene and one in the addressable asset bundles. When the addressable asset changes the scriptable object data it is not the same instance of the data you have in the scene, nor the other way around. They are now 2 separate data sets.

    I made my scriptable objects addressable and have them loaded while doing the bootstrap.
    Anything in my scene I instantiate by addressables now as well. So my scene is pretty much empty and only exists of behaviours that instantiate the prefabs. Not the best way but it is a workaround.

    In another scene (not included into the build) I have the prefabs instantiated so I can easily change something visually.

    But technically the better solution would probably be to make the scene addressable and have your bootstrap load the addressable scene. Any prefab that is in the scene or used in the scene will automatically be addressable as well due to dependencies of the Scene. So if you separate those into a different packing group in addressables you're able to change the prefab, do an update and it should reflect the changes in the scene then. (atleast in theory, have not tried it.. even though I should but time constraints, I'll try this at home at some point but too busy currently)
     
    Colin_MacLeod and Rafarel like this.
  8. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Thanks for your time @MaskedMouse !

    Something I do not understand is that when I call
    Resources.FindObjectsOfTypeAll
    to find all my ScriptableObjects of a certain type, when you are in Packed mode the method return all ScriptableObjects twice if the assets is referenced by a prefab and a scene even if all my assets and scenes are addressable. When I play in Fast mode
    Resources.FindObjectsOfTypeAll
    return the good count of object.
    Any idea ?
     
    Last edited: Mar 29, 2019
  9. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    I don't use
    Resources.FindObjectsOfTypeAll
    . I usually just reference the scriptable object in a serialized field.

    As the documentation mentions:
    https://docs.unity3d.com/ScriptReference/Resources.FindObjectsOfTypeAll.html

    In your case packed mode loads the prefabs into memory which is probably picked up by the API you're using.
    When you play in Fast Mode the assets are used from the project which may not be picked up directly?
    I don't use the Resources API at all. If I really need something from a Addressables I either reference the Scriptable Object directly or by another Asset Reference load using Addressables using the Addressables API.
     
  10. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Yes I'll not use
    Resources.FindObjectsOfTypeAll
    I was just curious about how many of my ScriptableObjects are in memory, trying to understand how all this works and why this method return some of of my assets in double just in Packed mode.
     
  11. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97
    So how can a ScriptableObject be loaded with addressables?
     
  12. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Your question needs a bit more context.
    Are you having the same issue?
    Or are you just trying to load a scriptable object asset using addressables?
     
  13. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97
    trying to load a scriptable object asset using addressables.
    With which code can I do it? I would like to host a scriptableobject on my server and have it downloaded. but I find only LoadAsset<GamebObject> ... what should i do ?
     
  14. LilMako17

    LilMako17

    Joined:
    Apr 10, 2019
    Posts:
    43
    if you have class MyDataClass which extends ScriptableObject, you can use Addressables.LoadAssetAsync<MyDataClass>(myKey) to load your scriptable object.
     
  15. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97
    I need to Load a scriptable object at runtime with addreaddable.

    I have a WeaponInstance component which refers to WeaponSharedData which is a ScriptableObject.

    I would like WeaponInstance to load the right WeaponSharedData using Addressable name or label could you show me the code ?

    My Key stands for? I would like to load with names..thank you sir!
     
    Mikael-H likes this.
  16. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    I the exact same use case. Did you find a good way to handle this?