Search Unity

Optimized ScrollView Adapter + Playmaker support

Discussion in 'Assets and Asset Store' started by thefallengamesstudio, Apr 1, 2016.

  1. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi there, fellow developers!
    We're happy to announce our complete framework for implementing a highly customizable ListView/GridView/TableView, or optimizing your already-existing, ScrollRect-based one.
    Useful for chat systems, leaderboards, inventories, view pagers, spinners, and actually for any kind list you can think of.




    Cheers! :D

    UPDATE 20.07.2020 - 5.1.0:

    Full Changelog

    Playmaker support is still included in OSA 5.1!
     
    Last edited: Jul 30, 2021
    Nananaaa likes this.
  2. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,479
    why there is no source code included?
     
  3. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Edit: Source code included starting with v2.1
    Old message:
    Hi John, we've explained this on the asset's page in asset store. check it out.
     
    Last edited: Jan 15, 2017
  4. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,479
    Then please provide a full width/height list demo, because all the list assets out there work when they are not covering whole screen area just like your example.
    Make your list cover whole screen area, and provide a demo , an apk and you got a new customer
     
    thefallengamesstudio likes this.
  5. Trinary

    Trinary

    Joined:
    Jul 26, 2013
    Posts:
    378
    People really like source, especially for a product that may be under development and not yet fully featured.
     
    Smokas likes this.
  6. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Didn't fully understand the "full width/height list" part(if you're saying the scrollviews should be fullscreen, that would imply we must have a toggle that shows either the horizontal or the vertical view, which would complicate further the demo), but we'll make the vertical scrollview in the first page cover the whole screen height, so it'll be the same as the one in the second page (the default mehod). And it's a great idea to give an actual APK as a demo. Here you go > https://www.dropbox.com/s/xm533zn8h4apgb2/ScrollRectItemsAdapter8 v2.0 - demo.apk?dl=0.
    And we'll put a link in the asset store for this apk as well when the next update comes (shortly). This link will be also updated regularly.
    PS: we're also working on a new video that'll show the implementation steps one by one. So it'll be both a demo and a tutorial.
     
  7. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    We're starting to think about sharing the sources. So many people want them... but I can't promise anything at this moment
     
  8. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,479
    Thats what i mean full height width
    http://applenapps.com/wp-content/uploads/2013/12/twitter_6_1.jpg
    As you can see Twitter List is covering whole screen height width except header and footer. secondly each item height is based on content, and thirdly its quite complex item.

    We are currently developing exact same List with NGUI, and NGUI is ultra fast, but we prefer a NewUI based plugin so we have the flexibility to use NewUI related stuff like TextMeshPro, Image/Raw Image related stuff etc.

    So please provide an APK like twitter list (with hardcoded data ofcourse) but this demo show both handling of images and variable height, and if it works well on my device, ill buy it immediatly even without source code.
     
    yuliyF likes this.
  9. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,479
    I just checked the demo and i started to have hope that it can be used but then i changed to variable item height and then it started to lag, it doesnt smoothly scroll with variable height and now im 100% sure that it wont scroll well with when you create above example.
     
  10. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Of course it's slower with variable sizes, but it shouldn't be way slower, as you describe it. You're doing something wrong, or seeing it wrong. I don't notice a FPS difference between having 10, 100, 1000, 10000 items, variable sizes or not. And also take note that in the demo app there are 2 scrollviews (horizontal and vertical) at the same time, so the performance is a bit slower than usual. If you say that the scroll view looses it's inertia(doesn't continue scrolling and decelerate after you released the click/finger), that's natural - it's the content's size that's too big that causes this. Too small of an issue to work on it now. But you really need to have like >1000 items for this to happen, and at that point, you should re-design your app's logic (i.e. do pagination). Also note that the prefab used there is a quite complex one (it has 14 children - just to cover the worst-case scenario), while you'll usually have 1-2 texts, and 2-3-4 images => 4-7 children.
    I can guarantee you can't go faster than this. We used this asset for ourselves and continue using it. If we would've found what we needed in the asset store, we would've bought it and didn't bother making our own optimizer from scratch. We squeezed every bit of performance from it. Trust me.

    PS: sources will be out for v2.1 - the package submission is in review
    Edit: v2.1 is out (+ fixes/improvements)
     
    Last edited: Sep 16, 2016
  11. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,479
    Alright, i really love you to prove me wrong because i personally dont want to plugin NGUI based List inside New UI, so if you can make a twitter example list with hard coded data with variable size (still 1 list in whole screen) and provide APK, then it will prove whether it can be used in production app or not.
     
  12. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    The APK linked above exposes all the features you can ask for in this asset. Did you tried it?
    Sorry, but another APK is really redundant... it doesn't matter if it's half of the screen or not.. it should work anyways. The optimizer only helps you recycle unseen items behind the scenes. You're setting the size/position at edit time as per your design document.
    PS: You have my word that this is and will be a serious asset with constant improvements and that it's implemented with both large and small projects in mind - especially the former
     
    Last edited: Dec 5, 2016
  13. TobyKaos

    TobyKaos

    Joined:
    Mar 4, 2015
    Posts:
    191
    Support grid layout for instance to show characters icones?

    And is it reparenting pooled or position based pooled?
     
    Last edited: Jan 5, 2017
  14. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    You can simulate a lot of scenarios using a "row" item prefab, a basic grid layout included. your items can be arbitrarily complex, arbitrarily wide/tall.
    Can't understand your second question, though. the items are parented to the Content game object of the ScrollRect. they are enabled/disabled/repositioned/updated during the scrolling (thus, recycling) process.
     
  15. TobyKaos

    TobyKaos

    Joined:
    Mar 4, 2015
    Posts:
    191
    My second question is about this article on unity: https://unity3d.com/fr/learn/tutorials/topics/best-practices/optimizing-ui-controls?playlist=30089

    You can read on the section Simple Scroll View element pooling that this approach have hiccup when setparent object to empty one that scrolled and be visible.
    A second solution more complex is to use
    Position-based Scroll View pools . In this implementation you will move transform instead of parenting it.

    I think your implementation use SetParent, right?
     
  16. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    From the beginning, we've targeted the most optimal way of pooling the items (that we were aware of at that moment) in order to increase the maximum number of items it could handle. We're talking about 100k-300k items of avg complexity (demonstrated in the demo video on the asset's page) - we thought more than this amount would be overkill and usually if someone needs to display so much items without paging, it smells as a bad design in the first place. In a very, very small nutshell, it's similar to "Position-based Scroll View pools". Item parenting is only done when that item is instantiated. If it's not visible, it will be disabled. If it goes too far outside (usually happens with variable-sized items or in the case of dynamically resizing the scrollview's viewport (or the scrollview itself) to a smaller height/width), it's destroyed, to obey our rule: the total number of instantiated items is number of visible ones + 1.
    But in the upcoming version this will improved further in the case of variable sized items, so that the number of destruction events will be reduced even more.
    We're actively improving/extending the optimizer and we're trying to implement as many feature requests from you as we can. For example, the next version will have a ScrollTo, SmoothScrollTo and RequestChangeItemSize methods. The last one allows you to request a new height(or width, in case of a horizontal ScrollView) for a specific item if it's visible - this can optionally be done for consecutive frames in order to obtain an expand/collapse animation, which is very common.
     
    Last edited: Jan 6, 2017
  17. TobyKaos

    TobyKaos

    Joined:
    Mar 4, 2015
    Posts:
    191
    Great, I have bought it.
     
  18. TobyKaos

    TobyKaos

    Joined:
    Mar 4, 2015
    Posts:
    191
    I think it will be great to use Interface and Abstract class to represent Data and Item.
    I have a base Class that inherit from another one and I cannot annd your ViewHolder base class.

    Edit: Ok that's because I have not well understand how to use it. I will add an holder class with an instance of my Item. Alongside a BaseParams class for holding what to see.
     
  19. TobyKaos

    TobyKaos

    Joined:
    Mar 4, 2015
    Posts:
    191
    Does you support Grid Layout? Seems not.

    Maybe to simulate it I must create a prefab with x Item horizontally? And my model mut contains X datas.
     
  20. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Right. A "row prefab" is the way to go in this case (assuming you have a (edit: sorry, I meant vertical) vertical ScrollView). So now the prefab used for an item in the ScrollView won't represent an individual data model, but a ROW containing 0 or more data models. You'll need to manage it yourself, depending on your particular requirements
     
    Last edited: Jan 8, 2017
  21. ddsinteractive

    ddsinteractive

    Joined:
    May 1, 2013
    Posts:
    20
    Downloaded and imported this just a few minutes ago. There is a console error "out of the box".

    "Assets/ScrollRectItemsAdapter8/Scripts/ScrollRectItemsAdapterExample.cs(53,52): error CS1061: Type `Button' does not contain a definition for `onClick' and no extension method `onClick' of type `Button' could be found (are you missing a using directive or an assembly reference?)"

    The line in question is this one:
    _ScrollRectAdapterParams.updateItemsButton.onClick.AddListener(() =>

    It seems that there is missing code in this Example script?
    Cheers,
    Monica
     
  22. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi Monica. Most probably, you already have a class called "Button" that hides the Unity's UI button class (UnityEngine.UI.Button) and updateItemsButton field in MyParams if of type Button (your Button), not UnityEngine.UI.Button. Hope this helps.
    Please let me know if you solved it,
    Lucian
     
  23. 2011drevil

    2011drevil

    Joined:
    Oct 29, 2013
    Posts:
    4
    Hi.

    The first time I called 'UpdateItem', nothing appears on the screen.
    When the screen is scrolled, the data is displayed.
    How can I force data to be displayed?
     

    Attached Files:

  24. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi.
    As a quick note, a "Refresh" is triggered each time you call Adapter.ChangeItemCountTo(int). There's no need for the number of items to actually change in order for the adapter to refresh. The adapter only requires you to provide the number of items via that call, the real/estimated size of each one (inside the GetItem[Height/Width](..) callback), and to instantiate/update the each one when they become visible (inside InitOrUpdateItemViewsHolder(..)). This process is fully documented in the manual & exemplified in the simple_tutorial.unity & its related script SimpleTutorial.cs.

    I know nothing about a method called "UpdateItem". Please be more specific. I'd speed up the debugging if you'd post your whole code that implements the adapter. You know the saying.. "just show us the code!"
     
  25. 2011drevil

    2011drevil

    Joined:
    Oct 29, 2013
    Posts:
    4
    Hi.
    Thank you for your quick response.
    As you pointed it out, we revisited the example and resolved the issue.
    Have a nice day.
     
  26. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Glad to hear that!
    Cheers
     
  27. 2011drevil

    2011drevil

    Joined:
    Oct 29, 2013
    Posts:
    4
    Hi.
    I have a new problem.
    I would like to receive an event called 'Scroll down' and continue adding items.
    Since I can not receive a lot of data at once from the database, I want to add items when I scroll down at the end of the current item.
    I want to know if there is a way.
    Have a nice day.
     
  28. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    This goes a bit out of context, because the optimal way of doing it requires you to think about how to balance the amount of data you'll request (doesn't make sense to continuously request chunks of x items if the user doesn't scroll to the bottom, but at the same time you'd want to have the data already available when the scroll amount exceeds half or 3/4).

    I don't recommend subscribing to ScrollRect.onValueChanged, because the adapter already does it, and there may be some interference if you'd change the number of items at the same time. Of course if you still do it and test it and in 20 out of 20 cases you have no issues, you're good to go. This is just a general recommendation.

    You'd need a small script (just to separate the functionality) like ItemsPagingManager(just an example name) that checks the current scroll amount once x frames or once a second via:
    ScrollRect.verticalNormalizedPosition or ScrollRect.horizontalNormalizedPosition - values from 1 to 0 or from 0 to 1, depending on scroll type.
    For example, if you have a vertical scroll type and want to add new items (already available) at the bottom, once in a while check if verticalNormalizedPosition drops below .25. If yes, add the additional chunk of items you have prepared and then request the next from the server. You can initially approach this by always requesting x+1 chunks of data in order to display x chunks, so you'll already have that 1 additional chunk ready to be displayed if you'll need to.

    EDIT: the periodical check for the scroll position should be done in Update or LateUpdate, even if you do it once a few frames/seconds. This is guaranteed to work. Other approaches must be tested first
     
    Last edited: Apr 15, 2017
  29. 2011drevil

    2011drevil

    Joined:
    Oct 29, 2013
    Posts:
    4
    Quick reply Thank you very much. As you mentioned, I'll test it by checking the location of the current scroll in 'Update' and then requesting data from the server.

    Thanks again.
     
  30. rattlesnake

    rattlesnake

    Joined:
    Jul 18, 2013
    Posts:
    138
    Hi ! I'm just digging into you plugin and it sounds really great (I'm a designer, not a coder though haha).

    I was wondering, is there any possibility to add later on a snap feature like this ? :
    https://www.assetstore.unity3d.com/en/#!/content/36671

    Right now I'm using the above plugin in order to view a photo gallery with the ability to zoom on a photo and continue scrolling in a full screen mode.

    Best regards,
    Seb
     
  31. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi rattlesnake!
    We were long considering adding an optional snapping feature, but no one actually requested it, so it was delayed. IDK about the zooming feature, as it's already something very particular, but it sounds really cool to press an item and maximize it. And the 2nd but: again, it's a particular feature to be able to also scroll in full-screen - I'm saying this because each use-case has very specific specs and the most optimal way of doing it is... drums.. manually. I really feel you guys as designers shouldn't dig into coding this and want something automated & configurable only in inspector, and that's why I think v3.0 would really be a game changer, because will let you this very thing. But until then, it's some 30-40mins of coding until you get the idea (you can see the YouTube video about it on the asset's page).
    If you're already using that asset and you're happy with it, and snapping is a must, I say stick with it :thumbsup:.
    But if some of our asset's current features really appeal to you, you can buy it and shoot a mail at contact@thefallengames.com with the invoice number telling us you'd like to have this feature and we'll start rocking, although we can't make any guarantee on how long it'll take.
    Best,
    Lucian
     
  32. rattlesnake

    rattlesnake

    Joined:
    Jul 18, 2013
    Posts:
    138
    Hi Lucian,
    Wouaw thank you very much for this detailed answer !
    I'm happy to hear that V3 will be much artist friendly :)
    The snap and zoom feature is not that urgent because I use my own workflow for now.

    However right now I have the following issue : my photo-gallery is on two columns like this :

    I'm using for that a Grid Layout Group.
    Is there anyway to make it works with the simple tutorial ?
    Best regards,
    Sev
     
  33. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    I'm here to help. :)

    So, because the adapter's first objective was to maximize performance, the code was written with extensibility/flexibility in mind for the user rather than a general ScrollView tool with a bit of everything (although after so much feature-requests were implemented, it slowly becomes so :)) which is not bad, because we still keep the extensibility factor along the way) and, if a programmer, he can easily adapt the optimizer for any use case. Thing like grids (which can be simulated by row-items if speaking of a vertical ScrollView) are an implementation detail and it'll take 10x more generalized code written by us than the code written just for a single particular case.
    But I'm almost sure that in the next release we'll put a basic utility script for common grid-like scenarios like yours, so the user won't need to bother with additional code compared to non-grid cases, if no fancy behaviors are needed.
    So to achieve something like in your picture with the current version, the concept of item will actually shift to the container of 2 images (that now conceptually become sub-items). And when the adapter tells you "give me the view of the item at position x", you'd give it the container of the 2 images for that position (this makes more sense after you're familiarized with how the adapter is used in code).
    Long story short: you're helpless without a programmer for v2.3 :D
     
  34. rattlesnake

    rattlesnake

    Joined:
    Jul 18, 2013
    Posts:
    138
    Hi Lucian,
    Every thing make sens.
    So for now, I need 2 differents scrollRect right ?

    I will send a mail to contact@thefallengames.com ;)
     
  35. ProjectBarBar

    ProjectBarBar

    Joined:
    Jan 28, 2017
    Posts:
    7
    Hi, How can I implement my own coroutine in InitOrUpdateItemViewHolder?
    "www.loadImageTexture" would be used to load image from web for each item.

    If I try to implement it, it says error of "Cannot access a nonstatic member of outer type "UnityEngine.Monobehaviour" via nested type "SimpleTutorial1.MyScrollRectAdaptor".

    "SimpleTutorial1.cs" is customized from simpletutorial.cs.

    Thanks
     
  36. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Just replied to your email, but I'll also post it here as a reference for others having the same question:

    You may use an image downloader helper in the end, that can also cache them for you, so you won't need to re-download them, but here's a quick solution until then:
    SimpleTutorial.cs inherits from MonoBehaviour, so one way of doing it is to pass it to the optimizer's constructor and reference it when downloading is needed. You'll implement a method in SimpleTutorial class for delegating the download task. something like this:
    Code (CSharp):
    1. public class SimpleTutorial : MonoBehaviour
    2. {
    3.     .. code ..
    4.  
    5.     // When constructing the Adapter, pass it <this>
    6.     _Adapter = new Adapter(this, ..other params..)
    7.  
    8.     // Wrapper helper to avoid calling StartCoroutine(DownloadImageCoroutine(..)) manually
    9.     void DownloadImage(string path, System.Action<Texture> onDone, System.Action onError)
    10.     { StartCoroutine(DownloadImageCoroutine(path, onDone, onError); }
    11.  
    12.     IEnumerator DownloadImageCoroutine(string path, System.Action onDone<Texture>, System.Action onError)
    13.     {
    14.         .. code for download with WWW ...
    15.         call onDone(...) or onError() after, depending on the case
    16.     }
    17.  
    18.     .. code ..
    19.  
    20.  
    21.  
    22.     // This is the already-existent inner class for the adapter
    23.     class Adapter : ScrollRectItemsAdapter8
    24.     {
    25.         .. code ..
    26.    
    27.         // New field
    28.         SimpleTutorial _Helper;
    29.    
    30.         // Constructor
    31.         public Adapter(SimpleTutorial helper, ..other params..)
    32.         {
    33.             ..code..
    34.        
    35.             _Helper = helper;
    36.        
    37.             ..code..
    38.         }
    39.    
    40.    
    41.         void InitOrUpdateItemViewsHolder(MyItemViewsHolder newOrRecycled)
    42.         {
    43.             ..code..
    44.    
    45.             // Very important to know which image was requested; if the image's path for the current view was changed after the initial image was downloaded,
    46.             // it means another image was requested for the same slot BEFORE the previous completed, thus we'll ignore the result in this case.
    47.             // See below
    48.             string requestedPath = .. get path from model using newOrRecycled.itemIndex..
    49.             _Helper.DownloadImage(
    50.                 path,
    51.                 // Called after download succeeded
    52.                 (downloadedTex) =>
    53.                 {
    54.                     string currentPath = .. get path from model using newOrRecycled.itemIndex (which may have changed)..
    55.                     if (requestedPath == currentPath)
    56.                     {
    57.                         .. use downloadedTex ..
    58.                     }
    59.                 },
    60.                 // Called after download did not succeeded
    61.                 () =>
    62.                 {
    63.                     string currentPath = .. get path using newOrRecycled.itemIndex (which may have changed)..
    64.                     if (requestedPath == currentPath)
    65.                     {
    66.                         // Do something; maybe display error image
    67.                     }
    68.                 }
    69.             )
    70.    
    71.             ..code..
    72.         }
    73.  
    74.  
    75.         .. code ..
    76.     }
    77.  
    78.     .. code ..
    79. }
     
  37. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Still one ScrollRect. The way you manage the items will be different. They'll be grouped: 2 per group, representing a row (with a HorizontalLayoutGroup for each row). But we'll keep in touch via mail and you'll receive an early release with this feature, so no need to think about it for now
     
    Last edited: Apr 23, 2017
    rattlesnake likes this.
  38. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
  39. iamthehunta

    iamthehunta

    Joined:
    Feb 17, 2014
    Posts:
    4
    Is there a pull to refresh data feature?
     
  40. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Nope, but sounds good. v2.4 was already submitted, but we may consider adding this feature in v2.5 if you'll shoot an email to remind us in a few days :)
     
  41. Rovnyy-K

    Rovnyy-K

    Joined:
    Apr 19, 2015
    Posts:
    4
    Hi guys. We've recently bought your asset and I am currently a little bit confused of extending it to support multiple prefabs. Do I have to create different view models for each prefab? It is also confusing to create multiple view holders, based on vastly different contents of associated prefabs. I would be happy to get some support on the process.
     
    Last edited: Apr 26, 2017
  42. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi and thanks for using the optimizer. There are a lot of ways to accomplish this, considering you only have one view holder and different prefabs.
    But worry no more: we already thought about thisfor v2.5. A few changes were made in the core module so multiple view holder types can co-exist under the same adapter instance, given they have a common base class. The current state: It's implemented and 90% tested. A new scene for multiple prefabs was added with a full example script. It's just not documented in the manual.
    Shoot at lucian@thefallengames.com with your invoice number and I'll send you the current package :)
     
  43. Rovnyy-K

    Rovnyy-K

    Joined:
    Apr 19, 2015
    Posts:
    4
    Thanks for a quite fast reply. I've sent the email.
     
  44. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
  45. rattlesnake

    rattlesnake

    Joined:
    Jul 18, 2013
    Posts:
    138
    Hello Lucian,
    The grid_exemple is working great when the URL's are online.

    However on android I have a frame-rate issue (then a crash) when the URL's are situated locally in Application.persistentDataPath

    Here is an exemple with the modified UpdateItems() function
    Code (CSharp):
    1. public void UpdateItems()
    2. {
    3.     files = System.IO.Directory.GetFiles (myGalleryFolder);
    4.  
    5.     // Generating some random models
    6.     var models = new BasicModel[files.Length];
    7.    
    8.     for(int i2=0; i2<files.Length; i2++)
    9.     {
    10.         models[i] = new BasicModel();
    11.         models[i].title = "Item " + i;
    12.        
    13.         string fileName = System.IO.Path.GetFileName(files[i2]);
    14.        
    15.         //models[i].imageURL = IMAGE_URLS[UnityEngine.Random.Range(0, IMAGE_URLS.Length)];
    16.        
    17.         //IPHONE
    18.         #if UNITY_IOS
    19.              models[i2].imageURL = "file://" + WWW.EscapeURL(files[i2], System.Text.Encoding.Default).Replace("+", "%20");
    20.         #endif
    21.        
    22.         //ANDROID
    23.         #if UNITY_ANDROID
    24.             models[i2].imageURL = "file:///"+files[i2];
    25.         #endif
    26.        
    27.         //Windows
    28.         #if (UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN)
    29.             models[i2].imageURL = "file:///"+files[i2];
    30.         #endif
    31.     }
    32.     _GridAdapter.ChangeModels(models);
    33. }
    Maybe the SimpleImageDownloader.cs have to be modified to be more efficient with local images ?
    Do you have any idea to resolve this issue ?

    Thank you very much !
    Regards,
    Seb
     
  46. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Hi Seb.
    That's why it's called SimpleImageDownloader. It's actually a primitive downloader with no caching or optimizations at all. It can only serve for demo purposes.
    What you have is more an optimization/platform-specific issue, rather than something related to the adapter.
    You can't get away without manual debugging, to see what the actual values are.
    I can only help you with some starting points:
    http://stackoverflow.com/questions/27440073/unity-www-local-image-url
    http://answers.unity3d.com/questions/517414/how-to-use-www-to-load-local-files.html
    https://docs.unity3d.com/ScriptReference/WWW.html

    Hope it was helpful
     
  47. rattlesnake

    rattlesnake

    Joined:
    Jul 18, 2013
    Posts:
    138
    Hello Lucian,
    I know how to use WWW class without issue for loading local URL.

    With my previous system it was working great. But with the plugin there seem to a memory leak somewhere.
    The code is the same that your grid exemple and the pictures are about 50ko.
    The only difference is that my URL are not online.

    I'm searching why, very strange...
     
  48. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Got it. See /// CODE /// section:

    Code (CSharp):
    1. protected override void UpdateCellViewHolder(MyCellViewHolder viewHolder)
    2.             {
    3.                 var model = _Data[viewHolder.itemIndex];
    4.  
    5.                 viewHolder.icon.enabled = false;
    6.                 viewHolder.title.text = "Loading";
    7.                 int itemIdexAtRequest = viewHolder.itemIndex;
    8.  
    9.                 string requestedPath = model.imageURL;
    10.  
    11.                 /// CODE ///
    12.                 // What should happen with the texture on the recycled viewHolder, if any?
    13.                 // Quickest solution: simply destroy it, of course;
    14.                 // Ideal solution: You can maintain a cache to avoid downloading the same texture again and again.
    15.                 // Regardles of the image's source, multiple Texture objects are created for each WWW request, so it's best to minimize them as much as possible if the texture for an URL/path is already created/cached
    16.                 if (viewHolder.icon.texture)
    17.                     Destroy(viewHolder.icon.texture);
    18.                 viewHolder.icon.texture = null;
    19.                 /// END OF CODE ///
    20.  
    21.                 SimpleImageDownloader.Instance.Download(
    22.                     requestedPath,
    23.                     //progress =>
    24.                     //{
    25.                     //    if (IsModelStillValid(viewHolder.itemIndex, itemIdexAtRequest, requestedPath))
    26.                     //        viewHolder.loadingProgress.fillAmount = 1f - progress;
    27.                     //},
    28.                     texture =>
    29.                     {
    30.                         if (IsModelStillValid(viewHolder.itemIndex, itemIdexAtRequest, requestedPath))
    31.                         {
    32.                             viewHolder.title.text = model.title;
    33.                             viewHolder.icon.enabled = true;
    34.                             viewHolder.icon.texture = texture;
    35.                             //viewHolder.loadingProgress.fillAmount = 0f;
    36.                             //DestroyImmediate(texture);
    37.                             //Destroy(texture);
    38.                         }
    39.                         //else
    40.                         //    Destroy(texture);
    41.                     },
    42.                     () =>
    43.                     {
    44.                         if (IsModelStillValid(viewHolder.itemIndex, itemIdexAtRequest, requestedPath))
    45.                             viewHolder.title.text = "No connection";
    46.                     }
    47.                 );
    48.             }
    The leak is 'platform-independent', so to speak :D. You're only creating textures, but not destroying the previous ones before replacing them
     
  49. bnooyen

    bnooyen

    Joined:
    Sep 17, 2012
    Posts:
    29
    I'm wondering if you could help me with something.

    I'm looking to utilize your Expansion package of the Unity3d Scrollview in my Unity3d Application. I'm primarily interested in the looping features.

    I have everything working just fine... the first time the list of items i loaded (currently 18 items). However, I'm having trouble re-loading that same list.. or using the same ScrollView to populate the listing of items with a lesser amount.

    I get a lot of 'argument is out of range' errors. I've looked at this for about 3 hours today and it seems like the easiest way to accomplish what I'm doing is to re-initialize the ScrollRectItemsAdapter8 each time I show the listing.

    I'm doing this by running a "_Adapter.Dispose()" to clear out all settings and destroy the necessary objects... however it appears that not everything is resetting.

    Once example is the newOrRecycled.itemIndex doesn't seem to reset. The first time I call the Init() method it runs as expected, where the index represents 0, 1, 2 and 3. However, the next time (after all of the Disposing) it represents 15, 16, 17, 18.

    Do you have a global 'reset' that I can apply to the ScrollRectItemsAdapter8 class, so that everytime I call the Init() method it acts as if its the first time it was loaded?

    This would save me quite a bit of trouble
     
  50. thefallengamesstudio

    thefallengamesstudio

    Joined:
    Mar 7, 2016
    Posts:
    552
    Just replied to your email, but for everyone else:
    ChangeItemCountTo(int) should do it.
    _Adapter.Dispose() disposes the adapter forever. This should only be called when the ScrollRect is destroyed.
    Re-using the adapter via Init() is not needed in most cases, because there are always easier solutions. But we'll make it re-usable (just for the sake of completeness) by clearing any cached resources inside Init() in v2.5 (coming in a few days).
     
unityunity