Search Unity

Destructible 2D ☄️ Dynamic Sprite Destruction

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

  1. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Some nice additions to the tool :)

    I am still hoping you will someday find a way to support really big destructible environments beyond just the iceberg-sized one. Like a large several-screen environment which can be just easily handled and interacted with without having to resort to other scripting. That would be almost a game in a box and would greatly elevate my interest in a purchase as well as for probably a number of other people, otherwise you're mostly supporting one-screen games or games which only have a few destructible elements.
     
  2. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Wouldn't this basically just be a tile map system? A quick look at the asset store shows there are quite a few already, and Unity will soon™ be releasing theirs, so I'm not sure if it's worth my time developing one.

    But if there are no decent free alternatives then I could write something simple to compliment the existing systems.
     
  3. _MGB_

    _MGB_

    Joined:
    Apr 24, 2010
    Posts:
    74
    I'm using Sprites, which are created from procedurally generated textures. Dragging a sprite into the ReplaceWith field at runtime works fine (updates both sprite and collision).
    Using a pre-made non-writable texture also failed to set the collision from script.
    No warnings or errors.
    Noticed that if I fiddle with the D2dEdgeCollider Detail slider afterwards, the collision is updated properly for the new sprite (must trigger a refresh).
     
  4. _MGB_

    _MGB_

    Joined:
    Apr 24, 2010
    Posts:
    74
    Ah, think I've isolated the offender: it works fine if I use a D2dPolygonCollider, but with the D2dEdgeCollider I was using it fails to rebuild the collision.
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I sent you a new build which should fix this issue.
     
  6. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    No not tilemaps... it would be a large per-pixel image like a landscape or whatever, not made from tiles.
     
  7. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I just tried some large textures with D2D (4000x2000 worms map, and 4096x4096 random shapes) and it runs more or less fine. You obviously can't enable splitting, because there's no way that can run fast on such larger textures. The main issue is that if your scene has thousands of colliders (because D2D splits it up into 64x64 or whatever size cells) then updating just one takes quite a long time. There isn't much I can do about the colliders, but one reason why games like Worms can run such large maps without lag is because they aren't generating colliders, and their objects collide against the raw alpha data. You can currently do this is D2D by reading the alpha value at a specific point in 2D, but there's no method to raycast the alpha data or anything which would be required for a game like Worms. I'll see if I can make some demo scene for this though.
     
  8. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Understood. But the system already has a way to represent a chunk of landscape. If the large landscape were divided into a coarse grid of those chunks, then it could still run at a good speed. All you need is to 'wrap' them in a higher-level controller of some kind which is capable of applying splits and explosions etc 'across chunk boundaries', ie if an explosion happens on a boundary you apply it to both adjacent chunks. The only part is combining parts from two or more chunks into a single dynamically moving chunk. This way you don't have to try recomputing the entire huge texture environment in one go, only the relevant local area.
     
  9. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I'll consider this for Destructible 2D V.3, as it would basically require rewriting all the code. I can see some issues with such a system though, like: if you have maps larger than 8k x 8k then how do you author the textures? How many people need maps this large? Even with coarse grids and other optimizations the color data itself wouldn't be optimizable nearly as much, so the filesize of each map would be huge.

    I think a far more sensible approach that works right now is to make your large maps from lots of small & medium sized sprites. For example in the old worms games the maps themselves were basically just terrains littered with large objects (merged into the same image of course). With some clever level design you could get it running basically the same but with full colliders, thus allowing way more advanced physics.
     
  10. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Anything past like 4k or 8k isn't likely necessary for most games. 4k fits 2x2 1080p hd screens. 8k would fit 4x4. And at lower resolutions, much larger. It doesn't necessarily have to go past a max texture size of 4096, but you have to split things up anyway. Leave it up to the developer to generate their game level, that part isn't difficult.
     
  11. pat68

    pat68

    Joined:
    Dec 15, 2013
    Posts:
    34
    Great Tool!
    I already bought the "old" Version (before 2.0) and my plan was to integrate this into Ferr2D.
    I found this documentation, but it looks this was valid for the older version of Destructible 2D:


    http://quantumyeti.com/blog/destructible-terrain-in-ferr2d
    The author also wrote a warning message at the top of his post.

    I know you're not the author of ferr2d, but as you look at the blog article, do you think this can be used for V2?

    Greetings
    Pat
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    No, that feature of Ferr2D has no relation to my Destructible 2D asset at all. They work completely differently and are thus incompatible.
     
  13. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    It would be great to have 'Min Pixels' setting without the need to use 'D2D_Splittable'.
     
  14. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    In the latest version you can use the D2dRequirements component in conjunction with the D2dDestroyer component to automatically destroy your objects when they fall below a certain amount of pixels (Alpha Count).

    If you create a destructible object using the 'Make Destructible (Preset: Dynamic Splittable)' then this destructible will automatically be set up to do just this.
     
  15. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    @Darkcoder i was talking about the possibility for simple, 'static' and 'dynamicSolid' presets to get ride of isolated tiny pixel islands colliders, not to destroy the whole object (unless i misunderstood your reply). This would for exemple prevent a caracter from being blocked by an almost invisible element.
     
  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I see, well in that scenario you still need the object to be splittable, else the solid pixel count won't get below this small value. You can then use the D2dRequirements component to disable colliders - just make it so that it disables the collider once the Alpha Count goes below a certain value rather than destroying it.

    In the future I plan to experiment with more advanced splitting techniques that only check for localized islands, as right now the splitting code isn't suitable for large objects.
     
  17. kbm

    kbm

    Joined:
    Aug 7, 2014
    Posts:
    84
    Hi, I love your asset and use it heavily in my game :) So far, everything's been working pretty much flawlessly but after upgrading to v2 (2.1 to be specific) I am missing a feature that used to be there and it's pretty important for me.

    When I split a Destructible, I used to be able to choose which part "survives" and which part gets cloned. I always want the biggest part of an object to remain and the new part(s) to become clones. This is important because I use Playmaker FSMs that need to remain in the correct state. Is there any way to still access this feature?

    Thanks!

    EDIT: I realize that maybe using the "On End Split (List)" Event I could get the data I need and then modify it? Unfortunately I failed at getting the List parameter to work in my script. How do I transmit the List of split GOs to a given script?
     
    Last edited: Nov 9, 2015
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Try opening D2dDestructible.cs and after line 1124 add:

    Code (csharp):
    1. groups.Sort((a, b) => b.Pixels.Count.CompareTo(a.Pixels.Count));
    So it should look like this:

    Code (csharp):
    1.  
    2.         public void Split(List<D2dSplitGroup> groups, int blurSteps)
    3.         {
    4.             if (groups != null && groups.Count > 0)
    5.             {
    6.                 groups.Sort((a, b) => b.Pixels.Count.CompareTo(a.Pixels.Count));
     
  19. kbm

    kbm

    Joined:
    Aug 7, 2014
    Posts:
    84
    Okay, I did this and I kind of understand what this does, but the Split Function still destroys the Original GO, right? Is there any way to prevent that? If I recall correctly, in Destructible 1.x this was the default behaviour?
     
  20. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    No, the original always remains unless every pixel has been destroyed below the minimum split amount.

    That code change just forces the original to use the data from the largest split part.
     
  21. kbm

    kbm

    Joined:
    Aug 7, 2014
    Posts:
    84
    Okay, I have another question that confuses the hell out of me: When I slice a Destructible Sprite, which clone gets added first to the List (the one that gets sent in the OnEndSplit() event) and which gets added after that? By what logic does Destructible2D decide this? I have a suspicion that the split object that's lowest (on the y-position) gets added first but I can't find out for sure.

    "No, the original always remains unless every pixel has been destroyed below the minimum split amount."
    When I select the original GO in Unity, it gets deselected from the Inspector. This usually only happens when the GO gets destroyed, so I assumed it gets destroyed.

    Anyway, I did some more trial and error and basically what I need to do is this: When I split an object, I need to access the part that's closest to some point / anchor and access the other (split) parts because I need them to do different things. I need the small parts far away from the anchor to fade via script and the anchored part not to fade. Is there any way I can have such granular control?
     
    Last edited: Nov 9, 2015
  22. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Unless you add the line of code I mentioned earlier, the first island/split will be the one that contains a solid pixel found when scanning from left to right starting from the top row.


    Indeed, if your selection disappears then it probably means it was destroyed. However, there is no code in the splitting methods that cause anything to get destroyed, so it must be something else (I said previously that if you destroy too much then it gets destroyed, but this actually isn't the case, as such a scenario wouldn't trigger a split).


    This sounds like a scenario where you would use the Fixture & FixtureGroup system. For example if you look at the 'Break Off' demo scene, you can see how the tree is being anchored to the ground, regardless off the actual split order.

    You can also see how to use fixtures in the 'Swinging Weight' demo scene, and there's also a small pdf explaining how it works.
     
  23. pat68

    pat68

    Joined:
    Dec 15, 2013
    Posts:
    34
    Hello,
    one question regarding the layers.
    I am using a rock as a prefab which has the layer "obstacle".
    If I test with "D2dClickToExplode" as in your demo scene it don't work as expected.
    The reason for this is that only one piece will retain the layer in the child object "collider". The other (generated) pieces will have set the layer to "default".
    I am following the "rule" not to colide everthing with everything and modified the layer collision matrix.
    As a result the generated pieces fall "through the ground".

    Can I do something to avoid this?

    Thank you.

    Greetings
    Pat
     
  24. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    This a bug I plan to fix in the next version of D2D, I'll send you a copy as soon as I test it!
     
  25. pat68

    pat68

    Joined:
    Dec 15, 2013
    Posts:
    34
    Hi Darkcoder, yes thank you.
    In the meantime I assign the layer to the child in the OnEndSplit-Event in D2dDestructible component.
    This works quite well.

    Another question:
    I want to hit the rock by a bullet and the rock should explode into pieces. The "D2dQuadFracturer" script seems usefull for this. I set the required damage value to one and it works.
    Before fraction, the rock is damaged as before without "D2dQuadFracturer" script. Can I avoid this? Only D2dQuadFracturer should do the work...

    Greetings
    Pat
     
  26. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I've fixed the layer bug. I also added a 'Damage Mask' field to the D2dCollider class, allowing you to limit impact damage to only your bullet layer, which should fix your issue?

    However, you seem to have disabled Conversations/Private Messages, so I can't send you the new build.
     
  27. pat68

    pat68

    Joined:
    Dec 15, 2013
    Posts:
    34
    Ok. Thank you.
    I've changed my account settings - it should work now.
    I will test your solution, perhaps this is enough. My first idea was to skip the impact damage from the bullet and instead let the "D2dQuadFracturer" do the work.
    Think like a bullet which don't explode on first contact, but a little delayed after it gotinto the object (here: rock).

    Greetings
    Pat
     
  28. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I see, in that scenario maybe you could remove the D2DQuadFracturer component, and write a very simple script that fractures the current D2dDestructible after a certain amount of time (by calling D2dQuadFracturer.Fracture directly). You can then use the D2dRequirements component to enable that script as soon as it gets damaged beyond a certain value. Anyway, I sent you a copy of 2.0.4!
     
  29. pat68

    pat68

    Joined:
    Dec 15, 2013
    Posts:
    34
    Thx for the fast response and the updated version. It works now!
    Regarding my scenario perhaps pictures are easier to describe my issue:

    Result without D2dQuadFracturer.
    Here the rock is damaged by a bullet. D2dQuadFracturer component is disabled.



    Result with D2dQuadFracturer.
    After enabling of the D2dQuadFracturer component, the rock is damaged AND fractured to pieces.
    What I would prefer is that only the fraction happens without damage.
    The pieces look a little bit "strange": (not realistic from my opinion)



    If I do the test with "D2dClickToExplode" it looks like expected ("no damage").

    Hope this is clearer.

    Greetings
    Pat
     
  30. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Ah I see, I was confusing stamp damage with destructible damage.

    In this scenario, I'm assuming you're using the D2dExplosion component to inflict the stamp damage as well as the destructible damage. If you just want to disable the stamp damage then you can set the Stamp Hardness to 0, or modify the code so it has a mask for the stamping that doesn't include this rock.
     
  31. treborguy

    treborguy

    Joined:
    Apr 17, 2014
    Posts:
    30
    Hi darkcoder. Considering buying, just have a question. I just read through the thread but I don't think anyone's asked this.

    I have a very specific gameplay mechanic in mind. Is it possible with destructible 2d to 'add' to the damage alpha, so that you can make parts of the mesh + sprite that were erased reappear by stamping?

    Thanks!
     
  32. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    No, right now you can only revert destruction to a previous state.

    The main problem with this kind of 'healing' feature is what happens if you heal pixels that were transparent or didn't exist in the original texture? Since D2D only modifies the alpha channel, healing such pixels will probably make those areas look bad. Also, what happens if a physics object is inside the healed area?
     
  33. treborguy

    treborguy

    Joined:
    Apr 17, 2014
    Posts:
    30
    Would it not be possible to just protect the pixels that were originally transparent from being altered? For my purposes I would never need to 'heal' pixels that didn't appear in the first place. The healing would cause problems for objects that were inside the healed area, for sure, but I would just limit the player from being able to heal such an area myself.

    Anyhow I bought Destructible 2D, it's great! I'm currently trying to figure out a workaround: store the alpha of the 'destroyed' object and subtract the shape you want to 'heal' from it then reset the alpha of the object you want to heal and use the modified destroyed alpha as a stamp on the clean one. That way no new pixels appear. It's gonna be messy, I'm an artist rather than a programmer :)
     
  34. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Indeed, if the original alpha data was stored then it could be used as a limiter for the healing. I'll see if I can add it to the next version.
     
  35. treborguy

    treborguy

    Joined:
    Apr 17, 2014
    Posts:
    30
    That would be amazing, cheers! Good luck with the next update!
     
  36. PaulJohnScott

    PaulJohnScott

    Joined:
    Jan 16, 2016
    Posts:
    1
    Hi Carlos

    Is it possible for a 2d player controller character (e.g. mario style) to interact with the destructible environment? I'm a complete n00b but getting there quickly! Thanks so much.
     
  37. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Yep, D2D uses Unity's built-in 2D physics system, so it should work with any 2D character controller and code.
     
  38. Eltayeb

    Eltayeb

    Joined:
    Jan 24, 2014
    Posts:
    20
    how can i set the alphatex to null, it's readonly and doesnt allow me to change it?

    what i want to do is to reset the gameobject to it's original state.
     
  39. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    You can call ResetAlpha() to rebuild the AlphaTex data from the source texture, or Clear() or ClearAlpha() to make it null, or ReplaceAlphaWith(...) to set it up to some specific state.
     
  40. Diet-Chugg

    Diet-Chugg

    Joined:
    Jul 4, 2012
    Posts:
    51
    I'm making an 8 bit game. Would it be possible to make an enemy shatter in a pixel perfect matter with this tool? (I'm trying to find an example of what I have in mind. If not I'll upload a custom animation showing what I'm imagining.) Also does this work with custom materials? I'm using Sprite Lamp's lighting materials.
     
  41. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    If you set the 'Blur Steps' to 0 in the QuadFracturer then yes you can get pixel perfect shattering.

    Yes this works with custom materials. but they have to be modified to support the 'AlphaTex' that Destructible2D generates to mask the destroyed parts. I'm not sure if it was in this thread, but I once modified the standard SpriteLamp shader to support D2D. There's also documentation detailing how to make the required changes if you're familiar with cg.
     
  42. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Hi, I was looking at the description of your asset and it mentions "fractures".
    How are they handled? Voronoi? Can the user customize the size of the chunks?

    I played with the demo, and I noticed all the eggs break in the same manner. Is there something like a "fracture image" that cuts them all in the same way? What if I wanted them to break randomly?

    Thanks for your time :)
     
  43. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Fracturing is handled by anything that inherits the D2dFracturer class. Right now there is only the D2dQuadFracturer implementation, which takes the sprite quad, and then subdivides it into 4 corners, jiggles the quad points around a bit, and depending on your settings may recursively keep doing this.

    This gives you a result similar to voronoi, but it's not really the same thing. If there's demand for voronoi fracturing then I can add it of course.
     
  44. NeatWolf

    NeatWolf

    Joined:
    Sep 27, 2013
    Posts:
    924
    Voronoi or similar would be good, or even other solutions of apparently random fracturing.
    It would be nice if it could enter the roadmap :)
     
    Darkcoder likes this.
  45. ObsidianSpire

    ObsidianSpire

    Joined:
    Sep 13, 2013
    Posts:
    48
    Hey, I was just curious about support for Unity 4.6/4.7?

    The store page says it requires Unity 5, but the first post says
    • NEW Support for Unity 4.5 & 5.0
    That first post hasn't been updated in a long time, so I just wanted to make sure it's still true.
     
  46. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    As of D2D version 2.0.0, support for Unity 4 was dropped. I haven't tested it in Unity 4 for a long time now, but I imagine the majority of the code would work in 4.3+, and I can provide D2D version 1.X.X upon request.

    I'll update the description, thanks.
     
  47. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    Hey guys, a user reminded me that I forgot to add the Car Driving & Damage scene that was in D2D 1. I've now finished implementing that in D2D, and will submit that tomorrow along with a few other small things :)
     
  48. ExcellS23

    ExcellS23

    Joined:
    Sep 22, 2015
    Posts:
    9
    How's it going, I'm trying to split a 2d sprite tree in half upon collision with another game object. The other object colliding with the tree has a trigger Collider. How would I go about writing this using your classes? Also is it even possible to make it split into with a ontriggerenter2d call?
     
  49. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,413
    I replied to your email about this question :)
     
  50. RodMath

    RodMath

    Joined:
    Oct 21, 2014
    Posts:
    13
    Hi - this looks great, is it possible to get it to work with a mesh renderer instead of a sprite?

    Working in 2d, I create a polygon in runtime, which is rendered as a simple mesh using triangulator. Is there some way I can get this to be destructable with this plug-in?