Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Destructible 2D ☄️ Dynamic Sprite Destruction

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

  1. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Yes, it's an optional shader used in that particular demo scene I used.
     
  2. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    thanks , i managed to get working (more or less) the worm style pixel based collision , but im gonna miss the box2D collisions to make the objects rebound properly so ... ill be watching to that new version that needs to be approved, hope they do it soon !
     
  3. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    sorry to ask but, do you have an approximate idea when the new version is going to be approved?
     
  4. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    No idea, maybe a few days, a week, no one knows. But if you (or anyone) wants an early copy the you can always PM/email me your invoice ID and I can send it manually.
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    It looks like Destructible 2D 1.1.3 was just accepted, and is now live on the asset store :)
     
  6. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    awesome, its really convenient to have all your purchases in the download manager and re-download and install with just one click , will get and will be your worst nightmare when it comes to asking for support!

    just kidding, hope not to bug you much ;D
     
  7. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    first question (lol) why colliders are not added to the sprite when i select make it destructible? i guess this changed from previos version and your tutorial is not updated?
     
  8. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    alright i see all is done now trough the gear menu
     
  9. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Colliders aren't added by default because you don't always need them, and also because there are 3 types of collides in D2D.

    The system is set up so it only uses the exact features you want, to maximise performance. I will make some updated videos soon!
     
  10. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    Hi again , Darkcoder , im reading the docs to try to find a way to do this but i think it's no posible?

    check the picture, is there a way to avoid tiny pixels to be separated on each explosion stamp? i mean just destroy them if island < x pixels?
     

    Attached Files:

  11. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Small islands are only destroyed when a sprite is split (i.e. when using D2D_Splittable). This is because finding pixel islands is quite expensive. There may be some efficient way to find small islands like this though, I'll think about it.
     
  12. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
  13. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    here a suggestion that just came to my mind, you could create a special super performance mode for pixel art games so alpha information should be binary (no half transparent values) the alpha texture could be reduced a lot using not a byte for each value but a bit, you would need to create your own alpha texture grouping pixels inside an int in the way of bits, so when you read the alpha texture looking for pixels to destroy it should be faster cause the size is way much smaller ... ? and then translate this bits and modify the real normal texture that unity uses to render the sprite, maybe reading bits as pixels could be pain in the a$$ , but this is how it was made back in the days in 16 bits computers.
     
  14. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Your idea would save on memory, but it would also increase the complexity of the code a lot, as well as be incompatible with all of the current systems. I also don't think it would speed things up much/at all, because the bulk of the processing done in D2D is when scanning through the pixels (e.g. creating collider edges), not due to memory allocation or texture data transfer.
     
  15. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    alright, yeah ... it would probably be to get complicated for nothing.

    another suggestion/request , i would like to access the alpha texture so i can reconstruct areas of the destructed region of a sprite, this will be a very useful extra of D2D

    my game run flawless now digging ground with D2D_ExplosionStamp , making your on tunnels is so fun , but it would be awesome to be able to create ground , that would open a full world of possibilities

    i have tried to access the alpha tex but i could not, i have seen the code in C and it is a get only property? , this should be easy to change myself buy im not expert coder plus i write in java script so i've got a little lost
    in addition i would also need to regenerate colliders of course...
     
  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    You can access the AlphaTex using the yourDescriptibleSprite.AlphaTex property, this will return the current Texture2D applied to the sprites. You can also get the raw data from the .AlphaData property. I don't use UnityScript so I'm not exactly sure what the issue might be, but you can try placing the D2D code in a special folder (e.g. Standard Assets or Plugins), and that should force it so get compiled first, thus allow you to access everything from other languages.
     
  17. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    we are right, i don't know what i was doing wrong, the AlphaTex property is readable, i managed to create ground by filling this texture back with SetPixels, but this new piece of ground of course has no collider, is there an easy function/method i can call to rebuild colliders? preferable rebuild only the affected cells ...

    thanks in advance
     
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    I didn't anticipate many people would need this functionality, so I didn't expose it.

    But basically you need to open D2D_Destructible.cs, and change the access modifier of 'private void NotifyChanges' to public. You then need to perform your texture changes, but you need to modify both the AlphaTex (if it exists), and the AlphaData. The AlphaData uses a byte (0-255) for each pixel, and the AlphaTex uses the float alpha channel, so you must do a bit of conversion there. Then you can call NotifyChanges with your modified rectangle area, and that will trigger the colliders and what not to get updated.
     
  19. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    done ! and working nicely , thanks for all the help
    question: why do you use AlphaData instead of reading the alpha texture directly? performance i guess?
     
  20. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    2 main reasons:

    1 - Reading a byte array is much faster than using GetPixel
    2 - It allows you to put the destructible sprite in a prefab without losing the texture data
     
  21. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    thanks for the replies, here one more question (lol)

    im trying to edit your code to make it build not regular colliders but LiquidPhysic2D collider, another great asset from the store, it is an implementation of LIQUIDFUN a modification of Box2D, yeah , unity 2D physics are a mod of Box2D but both engines are not compatible :-(

    so LiguidPhysics2D uses the original Box2D fixtures instead of Colliders etc... i thought that the best way to make these 2 assets to work together is to make D2D create fixtures instead of colliders

    so for the start i went to the file 2D_PolygonSpriteCollider.cs and tried to mod public

    public PolygonCollider2D Collider;

    with

    public LPFixturePoly Collider;

    but i get this error "LPFixturePoly does not exists in the current context” im a little bit lost when dealing with classes, that belong to other classes and all that class mess ...LPFixturePoly is the LiquidPhysics class for the polygon colliders but it can't be seen from your code ... how could i make it work?
     
  22. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Replacing the collider generation in D2D would be a difficult task if you're not proficient in C#. You can fix that particular error (assuming it's c#) by using the namespace that the LPFixturePoly class belongs to. e.g. using LiquidPhysics; or whatever it uses. But that's only the first step, actually filling that with data from D2D will be way way harder.
     
  23. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    ill ask them what namespace is it , and yeah, that its first step but i have been reading your code a lot today i think i have the way to go , , wish me luck ;D
     
  24. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    this is their response :-( "LP2D doesnt use a namespace* and LPFixturePoly is a public monobehaviour derived class." this doesn't help me at all , any ideas?
     
  25. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Then either it's not in your current project (I'm guessing this isn't the issue), or it's not written in C#, in which case you need to force the LP code to get compiled before D2D, but you're already doing this with D2D so you can access it with your UnityScript code right? Maybe you can find some combination of special folders that works, but I have no idea, as mixing languages like this is a bad idea.
     
  26. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    totally different thing ... am i doing something wrong or , on explosion stamp, why the AlphaData is filled with value 15 instead of 0 ... ?
    is it an antialiasing you do on the borders of the stamp?
     
    Last edited: Feb 1, 2015
  27. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    The AlphaData is a byte array, so each pixel has a value of 0..255. If the alpha is above 127, then the pixel is treated as solid. However, that doesn't mean data that isn't 0 or 255 is useless, as the in between values are used to create edges of different angles. I guess you could call this anti-aliasing. This is also how the DensityTex works, so if your stamp texture has a value of 255, then it will normally punch straight through your destructible sprites, but the DensityTex lowers this value, so it takes longer to do the same amount of destruction.
     
  28. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    edges of different angles ... understand, thats so smart ,ill mod my code to take decisions if its above 127 or not, thanks
     
  29. Nimdanet

    Nimdanet

    Joined:
    Jan 19, 2013
    Posts:
    38
    Hi,

    I'm really interested in this Asset. I just need to know one more thing: can I predict object trajectory?
     
  30. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    I'm not sure what you mean. This package allows you to damage and split sprites, so what kind of trajectory would you need to predict? All the physics uses Unity's 2D physics system, so if you can predict trajectories of normal 2D physics objects then you can do the same with this too.
     
  31. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    hi , i have this simple shader that replaces the grey scale information with a color in a second texture called color ramp and i am trying to combine it with the SpritesDefault (Destructible2D) with no luck, not sure if i am asking you too much, i have no idea about shaders but i have the feeling that for someone that knows what to do should be pretty simple, i hope i am certain :D

    Code (CSharp):
    1. Shader "ColourReplacement" {
    2.     Properties {
    3.         _MainTex ("Greyscale (R) Alpha (A)", 2D) = "white" {}
    4.         _ColorRamp ("Colour Palette", 2D) = "gray" {}
    5.     }
    6.     SubShader {
    7.         Pass {
    8.             Name "ColorReplacement"
    9.          
    10.             CGPROGRAM
    11.                 #pragma vertex vert
    12.                 #pragma fragment frag
    13.                 #pragma fragmentoption ARB_precision_hint_fastest
    14.                 #include "UnityCG.cginc"
    15.              
    16.                 struct v2f
    17.                 {
    18.                     float4  pos : SV_POSITION;
    19.                     float2  uv : TEXCOORD0;
    20.                 };
    21.                 v2f vert (appdata_tan v)
    22.                 {
    23.                     v2f o;
    24.                     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    25.                     o.uv = v.texcoord.xy;
    26.                     return o;
    27.                 }
    28.              
    29.                 sampler2D _MainTex;
    30.                 sampler2D _ColorRamp;
    31.                 float4 frag(v2f i) : COLOR
    32.                 {
    33.                 // SURFACE COLOUR
    34.                     float greyscale = tex2D(_MainTex, i.uv).r;
    35.              
    36.                 // RESULT
    37.                     float4 result;
    38.                     result.rgb = tex2D(_ColorRamp, float2(greyscale, 0.5)).rgb;
    39.                     result.a = tex2D(_MainTex, i.uv).a;
    40.                     return result;
    41.                 }
    42.             ENDCG
    43.         }
    44.     }
    45.     Fallback "Diffuse"
    46. }
     
  32. Jota

    Jota

    Joined:
    Jul 25, 2012
    Posts:
    3
    Hi,

    Is there any easy way to restart modifications without reloading scene again?
     
  33. Jota

    Jota

    Joined:
    Jul 25, 2012
    Posts:
    3
    Just another question:

    When I test on Galaxy S3, everytime I made an explosion, the screen freezes for 0.1 sec. Although it's a small amount, it makes the gameplay not fluid and player might become angry. I followed your youtube tutorial. Is there anything that I can make it lighter? I'm using "Detachable Trees" in my scene. Can this be a problem?
     
  34. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    You can reload the sprite damage by changing the AlphaTex to None in the inspector. Just keep in mind this will overwrite any Halve/Blur Alpha Tex settings, so you'll have to set that up again (this is done by design).

    The 0.1 sec freeze you mention is due to the complex calculations that must be done to check for split pieces, rebuilding colliders, etc. The demo scenes were designed for desktop/web, so you may have to reduce the detail of your AlphaTex (e.g. using Halve + Blur + Sharpen Alpha Tex), or reduce the Detail setting.

    Also, make sure you're using the latest version of D2D (1.1.4).
     
  35. UrosJoksimovic

    UrosJoksimovic

    Joined:
    May 22, 2013
    Posts:
    12
    Hi Darkcoder,

    First of all, I'd like to commend you for this asset. I'm a very happy user.

    Secondly, I'm a bit lazy to plow through the code so I'd like to ask you for a bit of help:

    I find it annoying when I'm left with very tiny pieces of the original sprite as I have a top down game so it's quite frustrating when you bump into something you can barely see. I've managed to avoid those with setting MinSplitPixels to 1 and MinPixels in D2D_Splittable to the desired amount.

    However, the only corner case that persists is the one where the splitting doesn't occur and I manage to destroy all but a few pixels of the object. Now I can easily solve this by using a custom script that will just check and destroy the object if its SolidPixelCount is below a certain threshold, however, I don't like checking that from an Update method as it seems too wasteful. Any tips on where/how I could more elegantly achieve such an effect?

    Keep up the amazing work!
     
  36. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    After a destructible sprite is modified, the 'OnAlphaTexReplaced' message is broadcast on the GameObject. So you could add your code into a method with this name, and as long as your script is attached to the destructible sprite GO, it should work as expected.
     
  37. UrosJoksimovic

    UrosJoksimovic

    Joined:
    May 22, 2013
    Posts:
    12
    Wait, this is done whenever there's an explosion that touches even a single pixel of the object?

    As far as I can see, that doesn't seem to be the case.
     
  38. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Yes, the Stamp method is the one that's called when explosions hit destructible sprites. If it modifies any pixels then the 'OnAlphaTexReplaced' message will be broadcast after all pixels have been written. This message is how the colliders get updated too, so it should be working.
     
  39. UrosJoksimovic

    UrosJoksimovic

    Joined:
    May 22, 2013
    Posts:
    12
    Sorry for the late response, my priorities have shifted elsewhere, I couldn't get it to work, but I'll do a more detailed investigation once I have the time and post results back here so we can see what's going on.

    Thanks for the prompt responses!
     
    Darkcoder likes this.
  40. blindmansays

    blindmansays

    Joined:
    Oct 27, 2014
    Posts:
    3
    Is there any way, when applying the stamp on click, to have a 'debris' sprite that is the shape of the new stamp-hole and the texture of what used to be there?
     
  41. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Kind of. If you replace your stamp texture (e.g. a circle) with an outlined version (e.g. a ring), and add the D2D_Splittable component, then when you stamp your sprite you'll get the original circle hole you had, as well as a smaller cut off part.

    Implementing this kind of feature properly would require a new Stamp method though, I'll add it to the todo list!
     
  42. blindmansays

    blindmansays

    Joined:
    Oct 27, 2014
    Posts:
    3
    Thanks! That'd be great! In the meantime I'll try the workaround.
     
  43. iviachupichu

    iviachupichu

    Joined:
    Feb 6, 2015
    Posts:
    28
    Hi, I was just wondering how well Destructible 2D generates concave colliders. From the web demo is seems like the banana bomb demo has a concave edge collider but the tree and asteroid demo seem to use concave hull.
     
  44. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    D2D uses the 2D colliders from Unity, of which there are two main types: Polygon Collider 2D, and Edge Collider 2D.

    Both support arbitrary polygon shapes, so there is no convex hull limitation, and thus you can destroy any shape you like and the colliders will be generated as you expect.
     
  45. iviachupichu

    iviachupichu

    Joined:
    Feb 6, 2015
    Posts:
    28
    Thanks for the clarification. There is still a little oddity in the web demo.

    Seems like the collider is wrapping around some parts where the alpha is 0 which leads to a sort of invisible border. Can't tell exactly what's happening without seeing the colliders in the editor. Definitely going to buy this asset soon regardless.
     
  46. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    That particular demo scene uses Unity's built-in automatic PolygonCollider2D generation system, which isn't very accurate, and gives very generous collider borders. If you want higher accuracy then you can use D2D's PolygonSpriteCollider which gives far more accurate results, but is a bit slower in some circumstances.
     
    iviachupichu likes this.
  47. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    hello , any chance you could make a version of D2D shaders using lighting?
     
  48. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    For Unity 4 or 5? I can make one tomorrow.
     
  49. DrKucho

    DrKucho

    Joined:
    Oct 14, 2013
    Posts:
    140
    that's great! , i am using 4 for now , but having the ones for 5 should be something good for your package i would say , using lights on sprites is kind of fake lighting but still very useful for many games
     
  50. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,404
    Done, you can get the Sprites-Diffuse (Destructible 2D) shader for Unity 4 from HERE.