Search Unity

Feedback [SpriteShape] any way to batch cache geometry?

Discussion in '2D' started by Baste, Mar 26, 2021.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    We have a lot of SpriteShapes in some scenes. In order to prevent loading scenes from taking forever, we need to check the "cache geometry" checkbox on the SpriteShapeController.

    But this is very cumbersome, as there's a ton of them, and going through them manually and checking all the checkboxes is a drag. The checkbox is not there if we multi-select SpriteShapeControllers, the code actually checks that
    Selection.gameObjects.Length == 1
    before drawing it, so we have to manually click one after one.

    We also can't cache the geometry through script without it being a major pain, what the checkbox actually does is two things:
    - set an internal bool
    - add/remove an internal component (SpriteShapeGeometryCache) to the same gameobject with HideFlags set to HideInHierarchy.
    Both requires quite a lot of reflection wrangling to do on our own, and we'd rather not have to do that.


    Could you please allow us to both set the geometry as cached through script, or at least allow us to use the checkbox when we multi-select SpriteShapeControllers? Or is there any way we can do any of those now that I'm not aware of?
     
  2. Cybertiger

    Cybertiger

    Joined:
    Dec 19, 2013
    Posts:
    35
    I am looking for the exact same thing.
    May i ask if you found any solution to this @Baste ?
    I also tried upgrading to 7.0.3 from 6.0.0 but still no option avaiable it seems. ;(
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    No, still nothing. We have to do the stupid reflection dance to make it work.

    Does anyone on the 2D team, like @rustum, have any insight in why this works this way? We really want to optimize the geometry on all of our sprite shapes as otherwise loading scenes takes a stupidly long time, but the UI design really wants to hide the existence of the caching feature, and makes it impossible to do at scale for users who are not tech savvy enough to dig through the source code.
     
  4. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    644
    While we evaluate ways to optimize static SpriteShapes, I would suggest considering the following :
    1. Please enable CacheGeometry for all static SpriteShapes (Will be visible when you enter Edit mode). This makes sure that Geometry is not generated on runtime and serialized instead. Note: Changes made to SpriteShapes on the runtime will NOT trigger regeneration of Spriteshapes and will always the static geometry cached instead.
    2. Always enable Burst for dynamic geometry. If the shape does not have overlaps or knots, please enable Tessellation on C# Jobs too. Enabling Burst ensures performant generation of Spriteshapes without incurring GC or Main-thread CPU cost and uses less memory.

    We will update this thread as soon as we have an update on batching. Thanks.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Hi!

    My point was that what we want to do is 1), but the workflow is horrible:
    - We can't do it when SpriteShapes are multiselected
    - It takes multiple clicks to toggle the checkbox
    - We can't check if CacheGeometry is set from script
    - We can't set CacheGeometry from script

    So it takes hours to deal with these when it should take minutes, and the only way for me to verify that they're batched is to got through all SpriteShapes in all scenes by hand.
     
    Will-Todd likes this.
  6. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    644
    Thanks for the feedback. Agreed, we will address them in an upcoming version of SpriteShape.
     
    MousePods likes this.
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    We ended up just forking SpriteShape to deal with everything that's bad, like this! Feel free to copy the code since it took you 6 months to figure out if/why/how to fix this internally:

    Here's the diff that fixes it:
    upload_2022-8-30_16-14-26.png

    Copy-pasteable version:
    Code (csharp):
    1.  
    2.             var cacheGeometryDisabled = false;
    3.             foreach (var t in targets) {
    4.                 var ssc = (SpriteShapeController) t;
    5.                 var targetIsPrefabSelectedInProjectView = !Selection.transforms.Contains(ssc.transform);
    6.                 if (targetIsPrefabSelectedInProjectView)
    7.                     cacheGeometryDisabled = true;
    8.             }
    9.  
    10.             using (new EditorGUI.DisabledScope(cacheGeometryDisabled)) {
    11.                 EditorGUI.BeginChangeCheck();
    12.                 EditorGUILayout.PropertyField(m_GeometryCachedProp, Contents.cacheGeometryLabel);
    13.                 if (EditorGUI.EndChangeCheck()) {
    14.                     foreach (var t in targets) {
    15.                         var ssc = (SpriteShapeController) t;
    16.                         if (m_GeometryCachedProp.boolValue) {
    17.                             var geometryCache = ssc.spriteShapeGeometryCache;
    18.                             if (!geometryCache)
    19.                                 ssc.gameObject.AddComponent<SpriteShapeGeometryCache>();
    20.                         }
    21.                         else {
    22.                             if (ssc.spriteShapeGeometryCache)
    23.                                 DestroyImmediate(ssc.spriteShapeGeometryCache);
    24.                         }
    25.  
    26.                         ssc.RefreshSpriteShape();
    27.                     }
    28.                 }
    29.  
    30.                 SpriteShapeUpdateCache.s_cacheGeometrySet = true;
    31.             }
    32.  
    I haven't run into any problems yet. Though,
    - The m_GeometryCached is horrendous - why are you tracking the existence of a component with a bool instead of just checking that the component is there? It's just introducing a way to have a bug that doesn't need to be there.
     
    Will-Todd likes this.
  8. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    644
    The idea was to separate the usage of Cached from the actual container of data through this variable so the original data is preserved and can be retained in playmode even if its modified. However you are right that at its present state (this option is not exposed) m_GeometryCached is redundant.

    Regarding Multi-Edit, there are a few scenarios where the usage can result in unexpected or slow behavior. Now that we have addressed a few by optimizing geometry generation, we will revisit this as soon as possible. Apologies for the inconvenience caused.