Search Unity

Destructible 2D ☄️ Dynamic Sprite Destruction

Discussion in 'Assets and Asset Store' started by Darkcoder, May 29, 2014.

  1. Bumblebee77

    Bumblebee77

    Joined:
    Sep 18, 2014
    Posts:
    7
    thank you
     
  2. hugesama

    hugesama

    Joined:
    Sep 24, 2014
    Posts:
    2
    Greetings, Loving the asset so far, but I have downloaded the latest version and as a result have ran into 2 issues:

    1) When it comes time to build and run my application, it gave an error stating that
    abstract void SetHideFlags(HideFlags hideFlags);
    was not being implemented correctly in the D2D_Colliders derived classes (I was able to fix this by moving the abstract declaration inside of the #if UNITY_EDITOR block, but I'm not sure that was the correct fix)

    2) When I create a prefab of a game object that has sub-game objects with destructible sprites, the SpriteRenderer's Material property doesn't carry the Sprites-Default (Destructible2D)(Clone) setting into the prefab, making the sprites not show up in the prefab nor instances of said prefab.

    The first problem is not a big issue (assuming I fixed it without breaking anything else), but I wanted to bring it to your attention.

    The second issue is pretty much mission critical for me, as I also need the sprite tinting option that was just added, so I can't really go back to an older version. If you can please assist, or update the code so this no longer happens, I will be most grateful.

    Thanks,

    David
     
  3. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    #1 is my bad, I encountered a last minute issue with the way hiding colliders works and didn't test it it seems.

    #2 I can't replicate, and looking at the code it seems fine. The way D2D currently works is that you set the 'Source Material' field in the destructible sprite, this way the material (and thus the shader) you want get built with your game, and at runtime the material is cloned and set in the SpriteRenderer. This is done because in Unity 4.5 there's a bug where you can't set two [PerRenderData] texture fields on a shader (e.g. the sprite texture and alpha texture), so I need to create a clone material for each sprite instance. The only way that I can see this system breaking is if the Source Material is set to something that belongs in the scene (e.g. a cloned material). Can you verify that the Source Material is set to a material in your project?

    If this doesn't fix it then please PM or e-mail me a small project or package demonstratng it.
     
  4. hugesama

    hugesama

    Joined:
    Sep 24, 2014
    Posts:
    2
    I went ahead and reset one of the sprites back to its regular sprite, removed your component, then made the sprite destructible again. It is now being properly added to the prefab's again. Just took a bit of time to do the rest of them, but I'm good to go now.

    Wish I could dig deeper into what caused it, but I'm on a bit of a time crunch right now. Super glad to be back up and running. Thanks much for the quick response.

    And thanks for the cool asset, it has been fun implementing into my project. I'll try to remember to link you to the demo of our game, if you are interested in seeing it getting used for some good old fashioned blood n gore.
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Awesome, I'd love to see your game!

    The sprite material system was originally different because I wasn't aware of this bug. So it's possible you made the sprites using a version that didn't have this workaround, and updating caused these issues.
     
  6. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    Hi, did you end up implementing the fracturing feature the way that user @Emphy described?
    Thanks
     
  7. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Fracturing has now been implemented in version Version 1.1.0 (released today). It doesn't work like Emphy describes, but instead the sprite is split up into randomly sized quads, with settings allowing you to choose how many pieces there are, as well as how jagged each piece can be. There is also a new component allowing you to make this fracturing automatic after a sprite has taken a certain amount of impact damage. Version 1.1.0 in fact added tons of new features and optimizations, so I'll post a more comprehensive release update post soon.
     
  8. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    UPGRADE NOTICE - Due to the massive changes made in this update, you will have to update your scenes to make it compatible with the new version, so please back everything up before upgrading. The main thing you have to change to update is to destroy the old automatically generated GameObjects used for the colliders. These should be called 'Edge Colliders, 'Polygon Colliders' etc, and should be children of your destructible sprites. Additionally, many of the components were renamed for consistency, so you may have to set their scripts again. Take a look at the new 'Upgrade Readme.pdf' to get more in-depth instructions.


    That's right, Version 1.1.0 is finally out, and it brings tons of changes:

    Fracturing - From the D2D_DestructibleSprite context menu you can now add the Quad Fracturer. This component will automatically split your sprite into the desired amount of pieces, and the max depth setting allows you to choose how many levels of recursion your fractured pieces can be fractured. The fracturing can be triggered based on the amount of damage the sprite has received (e.g. by impacts), or manually from the inspector or code.

    Splittable - The D2D_DestructibleSprite context menu now allows you to add the Splittable component. Previously splitting was handled in the D2D_DestructibleSprite component, but this code has now been separated, making it more modular and easy to work with.

    Colliders - Similar to the splitting code, the colliders have now been separated from the D2D_DestructibleSprite component. So from the D2D_DestructibleSprite context menu you can now add the Auto Sprite Collider, Polygon Sprite Collider, and Edge Sprite Collider. The Edge and Polygon colliders now also have improved performance, and the optimization/decimation code has been improved for performance and accuracy.

    Alpha Tex Subsets - Previously when you split a sprite in half (e.g. 256x256), it would result in two sprites each with their own Alpha Tex of the same size (e.g. 256x256). Version 1.1.0 now has code to automatically crop out parts of the texture that aren't used. This wasn't implemented previously because the code to do this is very complicated, but it's now been done and memory usage and performance is much better.

    Memory Usage - In addition to the subset code, I've gone through all the code and removed almost all parts that waste memory, or use the GC more than is required. This includes implementing pooling of certain objects, particularly in the areas of split calculations.

    Demo Scenes - I've added a bunch more demo scenes showing off the new features, as well some older features (e.g. Fixtures) that weren't shown to their full potential.
     
  9. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    Awesome! I can't wait to try this new version!
    Hey, by the way, is it possible when a sprite gets split, that I can set the cloned sprite to no longer be splittable, nor destructible for that matter? In other words, let's say you have a giant boulder and you break off a small piece of that boulder, I want that small piece to no longer be splittable, nor destructible anymore.
     
  10. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Good idea. This currently isn't possible but I'll add it to the next version.

    If you have any other ideas then please let me know :)
     
  11. Qwexar

    Qwexar

    Joined:
    Feb 7, 2014
    Posts:
    5
    I just bought your plugin and have been tweeking around your scenes to get the feel of how to use it. I installed it on my Ipad and its working fine (almost) but when i installed it in iphone 4 there is a certain delay before the destruction happens? Neither have i changed any code nor any settings. Every Setting is the default setting that came with the plugin example. Have you tested it on Iphone 4?
    the scene i used was "Impact" from the examples given in the plugin
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Does this happen on the first destruction only, or every time? Also, does clicking Halve reduce the amount of delay?
     
  13. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    This feature has now been added to Version 1.1.1, which should be on the asset store in a few days. If you want an early copy then please send me a PM or email. The way it works is you attach the new D2D_SplitLimiter component, and you can specify the minimum amount of solid pixels required to destroy/split/fracture a sprite, as well as the maximum split depth required for these to occur.
     
  14. Qwexar

    Qwexar

    Joined:
    Feb 7, 2014
    Posts:
    5
    It happens every time and on every point and i didnt quite understand that thing about halve you asked.. if you mean to ask the destruction on click is working fine or not that i havent checked that yet .. will check it out now
     
  15. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    At the top left of the demo scenes there's a 'Halve' button that will halve the width & height of the alpha textures, giving you around 4x the performance. I'll test it out on iPhone 4 soon.
     
  16. Qwexar

    Qwexar

    Joined:
    Feb 7, 2014
    Posts:
    5
    oh ok ... though one thing i did was i remembered.. I made the islands in the "Impact" Scene Destructible too....
     
    Last edited: Oct 16, 2014
  17. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    By the sounds of it the delay you notice is just processing lag, which is more noticeable on slower processors. Those islands are 470x276 pixels each, which is quite a large destruction image, especially on mobile devices. If you want to increase the performance of that then you want to click the gear icon at the top right of the D2D_DestructibleSprite component and click on Blur + Halve + Sharpen Alpha Tex, which should make it way faster without sacrificing much quality. If you applied other features to your sprites then be sure to check out the Performance & Optimization.pdf, which details various ways to speed your scenes up.
     
  18. Qwexar

    Qwexar

    Joined:
    Feb 7, 2014
    Posts:
    5
    Pressing the halve button does improve quality

    i examined the Halve button it decreases the solidPixelCount Property but i cant find this property in any variable. i wanted to change it in editor. i.e. (not during the game but before even starting it) which i cant seem to ? any help with that please?
     
  19. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    The code for that routine is in D2D_DestructibleSprite.cs line 54. You can call it manually via yourDestructibleSprite.CombinedHalveAlphaTex();

    The SolidPixelCount property is read only, because its value will only change if you destroy some parts of your sprite's Alpha Tex, or you replace the Alpha Tex, etc.
     
  20. Qwexar

    Qwexar

    Joined:
    Feb 7, 2014
    Posts:
    5
    ok Thanks... Awesome help :)... and awesome plugin i must say have been looking for it for a year now :)
     
  21. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    Thank you!
     
  22. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    The D2D_SplitLimiter wasn't exactly what I expected. But I love the new SplitDepth variable that is part of D2D_Destructible. I simply added the following method to D2D_Destructible to get the effect I wanted, which was to prevent all clones from being destructible...

    void Start(){
    if(SplitDepth>0){
    Indestructible = true;
    }
    }
     
  23. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Cool. I believe you can get the same effect using the SplitLimiter if you set the MaxDepthForDestructible to 0.

    The reason why I made it more complex than your original suggestion is because if you have a large sprite and chip off a tiny amount, it might not make sense for them to be treated equally. The additional settings allow you to disable destruction on smaller parts, but keep it on the larger ones.
     
  24. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    Oh ok I guess I'll play around with it some more. Some minor suggestions....
    - add documentation for D2D_SplitLimiter
    - add an example scene for it
    - in all of your example scenes include a brief onscreen text describing the intent of that particular example. There are a few example scenes that appear to demonstrate the same functionality, but i know that's not true.

    Anyway i love this plugin! Thanks!
     
  25. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Good idea, I'll add these in the next version :)
     
  26. heamaral

    heamaral

    Joined:
    Oct 11, 2014
    Posts:
    1
    Is there any way to add outlines with your shader?
    I want outlines always appearing on sprites that use your script.
    If it is possible, please tell me how can I add it.

    Like this:


    Thanks.
     
    Last edited: Oct 24, 2014
  27. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Nope, but I just added the new Sprites-Outline shader which has this feature. I sent you a private message with the latest build containing it.

    Here's a picture of it in action:



    Once I've added a few more things I'll submit version 1.1.2 for review.
     
  28. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    In the D2D_DestructibleSprite, how often is SolidPixelCount recalculated? I feel it should be recalculated more frequently. I'm using D2D_SpriteLimiter, and I have MinPixelsForDestructible set to 300. I slowly and continuously keep applying D2D_ExplosionStamp to the D2D_DesctructibleSprite and I'm able to "destruct" it way beyond 300 before the D2D_SpriteLimiter kicks in. By that time the SolidPixelCount has reached like 25.
     
  29. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Every time you modify the sprite it's marked as dirty, then if you try and access SolidPixelCount it will be recalculated.

    It's possible there's a bug in the code so I'll check it out later.
     
  30. RetrocadeNet

    RetrocadeNet

    Joined:
    Jan 26, 2014
    Posts:
    1
    I don't suppose there is a dumbed down version of this which only contains breaking sprite into multiple one which fly outwards and disappear after a moment? ;)

    Anyway a question - will this work with 2D Toolkit?
     
  31. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    That's basically the core functionality, so no :p

    D2D uses Unity 4.3's Sprite Renderer component which I assume 2D Toolkit doesn't use, so no it's not compatible in that regard. Though I imagine you could mix their sprites with the new Unity ones, but I don't know for sure.
     
  32. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    How about having a much lower resolution coarse grid representing `fully solid blocks` in the image being changed. This acts as a kind of coarse check.. you iterate over it (e.g. 16x less data to test with 4x4 blocks) and find any blocks which aren't connected to the others, to identify possible islands. Then for the islands, trace around the perimeter of the island only (i.e. ignore any cells which don't border on an empty cell). Then dig down to the per-pixel detail on those perimeter blocks and assume the rest are solid.? I guess you'd have to maintain two sets of data but it may make the slicing etc a lot faster.
     
  33. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    What if ;-) .. you don't have to update the collider for the whole sprite. Can you not keep calculations made from the previous state, and only modify a block containing an eplosion area, then recalculate only that area? Or maybe you do that already.
     
  34. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    On this note, why do you need to search the entire sprite to find islands? Why not search only the perimeter pixels around the outside of the `cut-out` shape, and try to trace like an a* path finding pathway to reach the 'ground'?
     
  35. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Why would you need to make a new texture, because your `finding islands` or `mesh generation` algorithms only work within one texture? Is it not possible to fake it where you e.g. create 2-4 separate `pieces` which span the edges of textures, and then group them somehow under one game object so they move together? Still separate independent pieces but visually they act as one?
     
  36. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Checking the perimiter is indeed one good method for speeding up split checking, but the actual splitting code would still need to perform a floodfill to find the pixels of the islands.

    Using a corse grid would allow for skipping of sections of the AlphaTex, but it still means you'd have to fall back to the original data quite often. Perhaps just storing everything in a quadtree would be the best of both worlds, but maintaining the tree would be quite costly. I'll experiment with it when I have more free time.


    This is already done by splitting the colliders into cells of 64x64 (or whatever square size), making it more smart would make the code a lot more complex.


    This would indeed be possible, but it would also be complex to implement. For example if you were to split a rock made from two sprites into a single falling rock you would need to create a root GameObject with a single Rigidbody, and there would have to be two child sprites. Additionally, it means the splitting code needs to cross sprite boundaries as it searches for islands. In effect this means the whole codebase needs to be rewritten for this scenario.
     
  37. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    The flood-fill part, what if you keep a grid of basic blocks and links that connect those blocks, then directly jump around those links (as if searching for `big pixels`) to find the islands, instead of flood-filling every single pixel?
     
  38. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Multithreading?
     
  39. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Feel free to experiment with the code yourself, I will try adding in quadtrees and test the performance. I imagine multithreading would give some benefit, but this doesn't seem like the kind of code that is the prime candidate for it.
     
  40. Ash-Blue

    Ash-Blue

    Joined:
    Aug 18, 2013
    Posts:
    102
    I really want to use this to create Terraria style pixel art destruction for my game by punching in some simple details. Our pixel size is pretty large, so it wouldn't be performance intensive for our game (http://playadnc.com). Am I easily able to do that with this plugin?
     
  41. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    It depends on the size of your maps, and your shader writing skills. D2D is designed for pixel destruction, but in a game like Terraria the terrain is made from 16x16 pixel blocks. Now it's very easy to make it so D2D destroys your images using 16x16 pixel blocks, but the edges of your terrain would fade between solid and opaque over a 16x16 block size, which wouldn't look good. However, if you were to write a custom shader to replace the smooth transparent edges with something jagged (e.g. rocks, grass, etc) then it might look pretty similar to Terraria.

    If you need the same kind of terrain features as Terraria then I would recommend you just use some sort of tileset system, as it will allow you to calculate collisions faster, give you more control over changing terrain tiles, and take up less memory. D2D would be more suited to allowing you to chop that tree down in your scene for example.
     
    Ash-Blue likes this.
  42. Dabeh

    Dabeh

    Joined:
    Oct 26, 2011
    Posts:
    1,614
    How will this handle over a network?

    If I have a 2D terrain and make an explosion at one point, will it look the same every time?
     
  43. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Yes, none of the D2D destruction code uses random values or relies on extremely precise values so it should look the same on all clients as long as the sprite has the same state at the time of the collision, and the destruction method you call has the same parameters. You'll have to handle this actual synchronization yourself though, as D2D doesn't have any networking code built in.
     
  44. DalerHakimov

    DalerHakimov

    Joined:
    Mar 14, 2014
    Posts:
    302
    Any holiday sales? ) like 50%+).
     
  45. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    I have no control over when my stuff goes on sale. I could manually halve the price, but in my experience this doesn't really translate to more sales because reaching out to new users is difficult without the front page featuring that Unity is able to provide. So no, there's no planned sale for at least a month.
     
  46. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    hello , this is my little game it is a pixels game so i need the pixels to be defined well, for that i use all graphics in a pixel 1:1 size, meaning each fat pixel you see in the game, is in reality a single pixel in the texture
    but the i've got this other asset that can dynamically destroy and create the background ( the brown rocks in the screen shot are shaped with this asset ) problem is the way it destroys the textures cuts my pixels creating sharp and perfect diagonal borders which are not what i want .
    QUESTION: would your D2D do the same ?
     
  47. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Yes, D2D would also create diagonal edges if your texture's alpha is using the type of aliased diagonal alpha you describe. It's possible to eliminate this by changing the alpha's filtering to 'point', but the colliders will still use this. The reason why is because it's must faster to create a diagonal, and it allows for much easier edge optimization. D2D was designed to integrate with Unity's 2D physics system, but a worms-style one bit collision system is best suited to custom collision system where you read the pixel's alpha rather than generate colliders.
     
  48. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    thanks for your answer, still not sure i want to make all scenery destructible, maybe just some of it and i have no idea about how to read pixels so maybe its better to purchase a framework .
    about colliders still being diagonal its ok , i already work that way.
    all my textures have point filter , but that didn't avoid the diagonals on this other asset i purchased, you sure your D2D will keep pixel shapes using point?
     
  49. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Yep, but the current version (1.1.2) doesn't allow you to do this so easily.

    However, version 1.1.3 makes this much easier, and is currently pending approval. Here's a picture of it in action:

     
  50. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    nice , but that back line? what is it? i guess is optional?