Search Unity

Multiple AssetReferences to the same ScriptableObject

Discussion in 'Addressables' started by ted-aronson, Feb 6, 2020.

  1. ted-aronson

    ted-aronson

    Joined:
    Dec 28, 2015
    Posts:
    8
    If I have several AssetReferences in different scenes which point to the same ScriptableObject, and I load one of those AssetReferences, should the others also be able to immediately access the SO, or do they each need to load as well?

    Context:
    In my current project, I have several instances of a ScriptableObject type called PlayerSkill. At the beginning of a game session, I create a dictionary which maps PlayerSkills to skill values and whatnot from the player's profile. Then, for the rest of the game I have various challenges that test these PlayerSkills. The challenges are generic enough that I've been able to create a handful of scripts that directly reference a particular PlayerSkill, which I hook up in the editor, and go from there. Challenges appear in multiple scenes which I load up through the Addressables system.

    When I first switched over to the Addressables system, the initial dictionary was essentially built by loading from Resources, and the challenges directly referenced the ScriptableObjects. That worked until I built to a device, and found that the challenges were getting cloned versions of the ScriptableObjects. That broke the whole dictionary system. I'm now considering building the initial dictionary using the Addressables system (still storing the PlayerSkills in the dictionary), and having the challenges use AssetReferences as well.
     
  2. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
    How are you loading the ScriptableObject? Are you using InstantiateAsync? If so, yes, it will instantiate a new clone for each InstantiateAsync call. If you are using LoadAssetAsync, it should return the same object for every call (though in that case it acts more like a prefab). If you want a single instantiated ScriptableObject, you will have to handle that yourself.

    I tend to wrap the system in my own manager and store pending operations in a private dictionary and ready objects in a separate dictionary, then when the caller requests that object through a public function, I either return the pending operation, or I create a new operation that is already completed with the ready object, or I start a new operation and cache that in the pending dictionary and return it. I use Promises for this, but you can also do it with Tasks (AsyncOperationHandle.Task will give you the pending operation).
     
    Last edited: Feb 7, 2020
  3. ted-aronson

    ted-aronson

    Joined:
    Dec 28, 2015
    Posts:
    8
    I've been using LoadAssetAsync. I wonder, though, if I've been thinking about the loading system incorrectly. In my system, I have 2 different AssetReferences pointing to the same scriptable object, and I call LoadAssetAsync on the first one at the beginning of the game. Later on, I try to directly reference Asset in the second AssetReference, assuming that since the first one loaded the scriptable object into memory it should just work without having to load again.