Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Loading SpriteSheet Sprites With AssetReference

Discussion in 'Addressables' started by andiPossess, Aug 29, 2018.

  1. andiPossess

    andiPossess

    Joined:
    Dec 2, 2017
    Posts:
    1
    There doesn't seem to be a way of referencing anything but the default sprite on a sprite sheet (in this case, a texture imported with Sprite Mode Multiple) using this system.

    Loading via LoadAsset<Object>() results in a reference to the texture. Loading via LoadAsset<Sprite>() results in a direct reference to the first sprite, it seems. Either way, I can't get to the data about the sprites in the texture.

    Additionally, there's no way to add addresses for each individual sprite packed into a sheet, so I can't do it that way.

    Am I missing something here?
     
  2. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    581
    I don't know :)
    We haven't spent as much time as we'd like testing all the workflows, and sprite usage is one of them. I've added a ticket to our system to look into this, and hope to poke at it next week. I'll get back to you once I've been able to spend some time checking on this sprite case, as well as a few others.

    Thanks for testing out the system.
    Bill
     
  3. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    581
    Hi, we've looked into this, and I've got a slight update. The short version is that sprite-sheets don't play nicely with asset bundles today, and Addressables is a wrapper around asset bundles. So sprite sheets don't play nice with addressables. We are looking into ways we could mask the problems by doing some under-the-covers magic, but we haven't worked it all out yet.

    If you broke your sprite sheet up, and then made it into a sprite atlas you could have a slightly better time. In this scenario, you could make the atlas addressable, and load it through our system. From there you'd need to load the specific frame you were after using https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlas.GetSprites.html

    This is something we could more easily create wrappers around so you could do the entire thing through addressables. We are looking into that as well.
     
    MNNoxMortem likes this.
  4. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    209
    So am I understanding this right, that there is no way to access the sub-sprites of a Multiple mode Sprite via code?

    Like I get not having looked at every use case under the sun, but how is "Iterate through sub-sprites by code" not right at the top of the list? Do you guys really expect people to set up their 2d animation clips using the Mechanim System? In production and at scale!? Come on guys... thats a complete mindless time sink that is totally unnecessary, and completely unsuited to rapid iteration in a large-scale production.

    I just assumed I would be able to write a simple script, that iterates through a multi-mode Sprite, at some FPS. It's really hard to believe this use case is not supported...I have a reference directly to the multi-sprite in the inspector, but somehow can not access it's children? Yeesh
     
    Last edited: Oct 3, 2018
    Alex_May and 5argon like this.
  5. Shlemon

    Shlemon

    Joined:
    May 17, 2013
    Posts:
    8
    I also think this feature is very important. Please add it soon!
     
  6. PaulBurslem

    PaulBurslem

    Unity Technologies

    Joined:
    Oct 7, 2016
    Posts:
    44
    With the latest addressables (.5.x), you can load sub assets (such as Sprites from a spritesheet) by specifying an IList<Sprite> or Sprite[] for your load type. Here is a quick example:

    Addressables.LoadAsset<IList<Sprite>>("MySpriteSheetAddress");

    This also works for getting animations from an fbx asset.
     
    arima_moto, MNNoxMortem and Shlemon like this.
  7. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    209
    Better late than never! Thanks Paul
     
  8. CapnCromulent

    CapnCromulent

    Joined:
    Sep 7, 2010
    Posts:
    43
    @PaulBurslem If I load a sprite sheet using IList, do I release each Sprite individually, or the entire IList?
     
  9. arima_moto

    arima_moto

    Joined:
    Nov 28, 2018
    Posts:
    5
    Hi!
    I am trying to load Multiple Sprite in various ways.
    (Addressables is 0.5.3)

    Code (CSharp):
    1. Addressables.LoadAsset<List<Sprite>>("Assets/Images/IconMaterial.png").Completed += op => { spritelist = op.Result; };
    2.  
    -> op.Result is null.

    Code (CSharp):
    1. Addressables.LoadAsset<Sprite[]>("Assets/Images/IconMaterial.png").Completed += op => { spritelist = op.Result; };
    2.  
    -> Error
    Assertion failed on expression: 'Thread::EqualsCurrentThreadIDForAssert(Thread::mainThreadId)'
    GetGfxDevice() should only be called from main thread

    Isn't there a good method for that?
     
  10. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    38
    We're finding that op.Result is null when attempting to load Sprites

    Code (CSharp):
    1. yield return Addressables.LoadAssets<List<Sprite>>(keys, op => {
    2.     Debug.Log("Loaded: " + op.Result);
    3. }, Addressables.MergeMode.Intersection);
    Will continue to investigate by loading Texture2D/SpriteAtlas, but we're not familiar with SpriteAtlas, so it could be fiddly.
     
    arima_moto likes this.
  11. DigitalSalmon

    DigitalSalmon

    Joined:
    Jul 29, 2013
    Posts:
    38
    For further info. when op.Result is null, op.OperationException is as follows:

    UnityEngine.ResourceManagement.UnknownResourceProviderException: Exception of type 'UnityEngine.ResourceManagement.UnknownResourceProviderException' was thrown., Location=...

    Also - Unity 2018.3.3f1, Addressables 0.5.3
     
    arima_moto likes this.
  12. arima_moto

    arima_moto

    Joined:
    Nov 28, 2018
    Posts:
    5
    Hi,

    I decided to use SpriteAtlas after all.
    Since it seems that a new version will appear in February, I am waiting for it.
     
  13. Dawar

    Dawar

    Joined:
    Dec 7, 2014
    Posts:
    116
    Addressables.LoadAsset<Sprite>("character").Completed += op => { image.sprite = op.Result; };
     
  14. BrothaMan

    BrothaMan

    Joined:
    May 19, 2013
    Posts:
    46
    Not sure if this has worked for anyone else, but each solution did not work for me in 0.7.5 in 2018.3.12f

    The example below only works in "Fast" Mode.

    Addressables.LoadAsset<IList<Sprite>>("MySpriteSheetAddress")

    Otherwise, for example in "Virtual" mode, I receive the following two errors:

    Exception encountered in operation Resource<IList`1>(Mooba Pre Match - Red.png): Provider of type UnityEngine.ResourceManagement.ResourceProviders.Simulation.VirtualBundledAssetProvider with id UnityEngine.ResourceManagement.ResourceProviders.BundledAssetProvider has provided a result of type System.Object which cannot be converted to requested type System.Collections.Generic.IList`1[UnityEngine.Sprite]. The operation will be marked as failed.
    UnityEngine.ResourceManagement.ResourceProviders.Simulation.InternalOp:RequestOperation_Completed(VBAsyncOperation`1)
    DelegateList`1:Invoke(VBAsyncOperation`1) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/Util/DelegateList.cs:69)
    UnityEngine.ResourceManagement.ResourceManager:Update(Single)
    MonoBehaviourCallbackHooks:Update() (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/Util/MonoBehaviourCallbackHooks.cs:19)

    Exception: Provider of type UnityEngine.ResourceManagement.ResourceProviders.Simulation.VirtualBundledAssetProvider with id UnityEngine.ResourceManagement.ResourceProviders.BundledAssetProvider has provided a result of type System.Object which cannot be converted to requested type System.Collections.Generic.IList`1[UnityEngine.Sprite]. The operation will be marked as failed.
    UnityEngine.ResourceManagement.AsyncOperations.ProviderOperation`1[TObject].ProviderCompleted[T] (T result, System.Boolean status, System.Exception e) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/AsyncOperations/ProviderOperation.cs:118)
    UnityEngine.ResourceManagement.ResourceProviders.ProvideHandle.Complete[T] (T result, System.Boolean status, System.Exception exception) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/ResourceProviders/IResourceProvider.cs:95)
    UnityEngine.ResourceManagement.ResourceProviders.Simulation.VirtualBundledAssetProvider+InternalOp.RequestOperation_Completed (UnityEngine.ResourceManagement.ResourceProviders.Simulation.VBAsyncOperation`1[TObject] obj) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/ResourceProviders/Simulation/VirtualBundledAssetProvider.cs:82)
    DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/Util/DelegateList.cs:69)
    UnityEngine.Debug:LogException(Exception)
    DelegateList`1:Invoke(VBAsyncOperation`1) (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/Util/DelegateList.cs:73)
    UnityEngine.ResourceManagement.ResourceManager:Update(Single)
    MonoBehaviourCallbackHooks:Update() (at Library/PackageCache/com.unity.addressables@0.7.5-preview/Runtime/ResourceManager/Util/MonoBehaviourCallbackHooks.cs:19)


    Trying to figure out what LoadAsset type I need to pass in order for the Resource Manager to know it should be loading a collection of Sprites and not a single Texture2D.

    Unfortunately, this is a big time blocker for me to use Addressables if there isn't away to load Sprites from a spritesheet. Too far into development to switch my spritesheets to SpriteAtlas

    Also tried the LoadAssets method, couldn't get that to work either.
     
  15. BrothaMan

    BrothaMan

    Joined:
    May 19, 2013
    Posts:
    46
    @unity_bill Any chance you can help with my question above about loading spritesheets through addressables?

    Basic Addressables.LoadAsset<Sprite> doesn't work on a single sprite png for me either. I tried to load by string pointing to the Asset and by AssetReferenceSprite, still only expects to load a Texture2D and not a Sprite
     
    Last edited: May 9, 2019
  16. unity_bill

    unity_bill

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    581
  17. WillJey

    WillJey

    Joined:
    Feb 12, 2019
    Posts:
    1
    Hi, @unity_bill, @BrothaMan
    Addressables.LoadAsset<IList<Sprite>>("MySpriteSheetAddress") fail in the virual mode.
    There's bugs in VirtualAssetBundle.LoadAssetOp<TObject> : VBAsyncOperation<TObject>. Where TObject is ALWAYS System.Object. I Thinks TObject Should Be 'IList<Sprite>'.
    Sorry for my poor English.
    Check on Latest
    [0.8.6] - 2019-05-14
     
  18. BrothaMan

    BrothaMan

    Joined:
    May 19, 2013
    Posts:
    46
    Thanks @unity_bill

    So if I understand correctly, as of v0.8.6, loading sprites from a spritesheet is not supported, as it will throw the error that @WillJey and I have found. In a future version, this will be fixed and when it does, you will provide an example of how to use it in the samples area of github link you provided above.

    Is that correct?