Search Unity

Destructible 2D ☄️ Dynamic Sprite Destruction

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

  1. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
    Hey I was trying to create a new mechanic where the player could use a "screw" object to attach two or more destructible objects together. It looks like the d2d fixture wasn't built for that. I was thinking I'd send out a call when an object splits to all connected screws to detach and reteach to whatever they are colliding with in one frame. Where is the best place to add that call within the "d2d splitter" script? Should I do it just after "destructible.SplitEnd", and how can I call the current object being split?
     
    Last edited: May 11, 2020
  2. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
    I'm still so stuck on this...trying to call this sort of event on "split-end":

    CustomEvent.Trigger(targetGameObject, argument1)

    Like I said in my previous post my intent is to check on multiple objects that are attached to the split object at time of split.

    I tried adding a reference to the game object in public static void TrySplit() but I think there's too many external scripts relying on it having 3 arguments. I'm really pulling my hair out on this one, if you can help me out on this one it would be a lifesaver.
     
  3. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
  4. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Sorry for the late replies!

    I've made a new component that supports sprite shape, but for some reason it seems to cause random crashes on Mac, so I don't want to include it in the main asset until I find the cause of this.


    Thanks! Indeed, this asset has gone through many changes over the years :)

    For this mechanic you could use the FixedJoint2D to connect both objects together. The joint's ConnectedRigidBody would have to be continuously set based on the parent Rigidbody of the other fixture (because when split it may change). You would also have to destroy or disable the joint if either of the fixtures gets destroyed. I think this setup would work, though it would require a custom script. Let me know if you need help implementing it.
     
    Last edited: Jun 17, 2020
    Dirly likes this.
  5. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
    Yeah I had come to the same idea as you, but I got stuck trying to find the right moment in which to signal the change in connected rigidbody.

    My plan was to send a CustomEvent.Trigger to a script of mine during TrySplit(), so whenever the object is split all joints that it's attached to will preform a cast to see if they are still connected to the same object. As I mentioned in my last post I tried adding a reference to the game object in public static void TrySplit() but I think there's too many external scripts relying on TrySplit() having 3 arguments. You have any ideas for this?
     
  6. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    The attached package almost works. I thought using a separate Rigidbody2D to bind both sides together would be an elegant solution, but it seems they don't maintain their angle properly. I'll try my previous idea next.
     

    Attached Files:

  7. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
    Using your old code I made a system that did a cast every time an object was damaged to see what object was directly under a joint and change to that object. That wasn't a very efficient method, but do you think if it only checked on split this would be a worthwhile solution?
     
  8. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    I managed to fix the previous test. It turns out the Rigidbody 'drifting' was caused by constantly setting the .connectedBody property to the same value, which for some reason causes it to recalculate something and lose data. This updated script now fixes that, and I recommend this approach due to its simplicity.

    If you have hundreds of these binds where using Update like this might be an issue then you can hook into the split events so you only have to check after each split, or you can write some kind of manager that quickly loops through and updates all of these.

    I'll tidy this code up a bit and make it into a new demo scene for an upcoming version.
     

    Attached Files:

  9. jarbleswestlington_unity

    jarbleswestlington_unity

    Joined:
    Dec 6, 2017
    Posts:
    32
    I think I'm going to set it up to only check at the end of the frame where a split is checked for and see how that works, thanks for the help!
     
    Darkcoder likes this.
  10. Meatloaf4

    Meatloaf4

    Joined:
    Jul 30, 2013
    Posts:
    183
    Hey hey it's been a while since I last played with Destructible2D. I was just curious if you the calculation of the density was added since my last post. Reference here. I went ahead and looked at the release notes but didn't see anything in relation to it.

    Thanks in advance!
     
  11. Exentro

    Exentro

    Joined:
    Oct 8, 2013
    Posts:
    36
    Hello,
    I was wondering if the asset could be used as eraser on a texture (use case would be an app for children that erase part of a drawing, which trigger something when a % of the image is erased). It seems drawing a line and using it as the texture to apply a change is not handled (2 closest are the stamp that only use a texture and the slice that stretch a predefined texture). Am I missing something ?
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Destructible 2D isn't really designed for this scenario, and may be a little slow. However, my other Paint in 3D asset would be very well suited for this ;)
     
  13. Landev

    Landev

    Joined:
    Jan 20, 2016
    Posts:
    1
    Hey,

    Great looking product! Question: How well does Destructible2D suit a worms-style game? As in having the terrain be destructible, but do not enable the physics portion (terrain shouldn't fall/break). I've read that networking is not included, but is doable to implement this myself? Would you recommend using it for this purpose? Thanks
     
    Dirly likes this.
  14. Dirly

    Dirly

    Joined:
    Mar 24, 2013
    Posts:
    19

    This is what I am soooo looking for. I was hunting all over, dont suppose you have an ETA on this? As it really changes the way I would setup my art. Still in the prototyping phase.
     
  15. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Hey @Darkcoder and thanks for awesome plugin! I'm experimenting a bit with fractures and I find them a bit too "random". Is it possible to change to behaviour without going into the code too much?

    I would like a behaviour like my attached image. The red points indicate where I press and the white indicates where I want the fractures to be.

    Basically I want the fracture to appear at the closest/shortest possible distance from the impact point (and not be random direction, but rather target the closest edge).

    fractures.png

    EDIT:
    Is this wrong/typo or intended? You're using the width instead of the height for the y-value.
    voronoi.PNG
     
    Last edited: Aug 7, 2020
  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Destructible 2D isn't designed with single large 'terrain' style sprites in mind because they take up a lot of memory and are hard to optimize, but they are possible. The far better idea is to make a large terrain from many smaller parts, then it will probably run faster and you have more control.

    Of course you could implement networking yourself, but it depends on your programming skill. At the bare minimum you need to transmit when and where destruction occurs (e.g. explosion prefabs), but in more complex scenarios you will need to sync the actual destruction data which is mostly just an array of pixel data, and other information about it like width/height/offset.

    I don't have a Mac to test on and when it crashes it's apparently seemingly random with no log information, so it may be a while before I release this feature.

    Yes that's a bug, nice find.

    The scenario you describe can almost be done the same with a little modification to the fracturer. As you can see in that method, it randomly picks fracture points inside the destructible shape, then fractures it using a voronoi diagram. In other words, each point creates a fractured part, and each pixel is assigned to the closest point. Therefore in your scenario you just need to place 3 points: one in the center of the top right slice, one in the center of the bottom right, and one to the left of where both lines cross.

    To implement this you would have to modify the TryFracture method to no longer call GenerateVoronoiPoints (or just modify it), but to instead create the points based on your slice points or however you define where they are.
     
  17. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Hey again Darkcoder, I understand what you mean and it would prob be easy to do... BUT i'm having problems converting local space coordinates to "alpha coordinates".

    Example:
    I pass along your initial RaycastHit2D-object to the TryFracture method, I then transform the world position of the hit.point into local space by doing:
    var localHitPoint = hit.transform.InverseTransformPoint(hit.point);

    But the "voronoiPoints" array is based of pixel/alpha positions and not actual world or local positions which complicates things. So how would I go from a local-space position to their respective alpha points in the array? I thought I could use the desctructible.AlphaOffset to figure out the position (since the coordinate-system get skewed once things starts splitting), but I'm doing something wrong :/

    tl;dr I wanna get the pixel that I actually pressed instead of the local position of where I pressed.
     
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    You can use the WorldToAlphaMatrix from D2dDestructible(Sprite), just multiply your world point by this and you'll get one that matches the 0..1 AlphaData. You can see the SampleAlpha method for an example usage.
     
  19. Maisey

    Maisey

    Joined:
    Feb 17, 2014
    Posts:
    302
    Duuh! Totally missed this! Thanks again!
     
    Darkcoder likes this.
  20. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Well my API generator currently doesn't parse inherited members, so I can't blame you :D
     
  21. EvilElephant

    EvilElephant

    Joined:
    Sep 29, 2017
    Posts:
    5
    Hello @Darkcoder.
    Do you know if I can use this in 3d game, where the 2d sprite would represent dirt on the floor, and then use that melting effect so it looks like you are cleaning the floor?
     
  22. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    This might be possible, but my other Paint in 3D asset would be much better suited.
     
  23. xSNOWM4Nx

    xSNOWM4Nx

    Joined:
    Jan 9, 2017
    Posts:
    3
    Hello @Darkcoder,

    I am a user of your assets and I really like it. I try different concepts to create a destructible underground with tiles. To get a good performance I use the "Optimize" function, which brings a noticeable increase. But the corners of my tiles disappear due to the "optimizations".

    Without optimizations, Tiles have no gap


    Optimized 2 times (Pixel option = Smooth)


    Optimized 2 times (Pixel option = Pixelated)


    Optimized 2 times (Pixel option = Pixelated, OverrideSharpness option = 200)


    Do you have an idea what else I can try?

    Thanks
     

    Attached Files:

  24. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    To fix this you can manually optimize the texture. You can open your image in your favorite image editing program, reduce the size to your desired size, and paint the corners solid so they don’t fade out like this. You can then replace the AlphaTex with your new image. I can give you more specific steps when I get back in a couple days!
     
  25. mrFisty

    mrFisty

    Joined:
    Dec 15, 2017
    Posts:
    4
    Hi, does Destructible 2D work with the Corgi Engine? I read from the docs:

    When adding the D2D Polygon Collider to a character prefab using the Corgi Engine, the console throws the following error message:
     
  26. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    It should work, at least with the environment.

    D2dCollider.cs has some code on line 150 that tries to delete any existing colliders, but you can comment out or delete this line.

    Keep in mind that if the Corgi Engine character controller requires a BoxCollider2D then it may not make sense to add a D2D collider alongside it. You may have to keep the BoxCollider2D and just settle for cosmetic damage only. You can probably mess with the layers and collision layers to do something in between, but it's probably not possible to just replace the BoxCollider2D with the PolygonCollider2D that D2D generates.
     
  27. Bit9Labs

    Bit9Labs

    Joined:
    Mar 24, 2013
    Posts:
    9
    Sorry if this has been asked. I'm returning to an old project. Does D2d work with canvas elements? Specifically I'm dealing with layout issues and It would be nice if I could use D2d Destructible Sprite on a native UI Image. The only difference I can tell is a dependency on a Sprite renderer vs an Image which in my mind is a sprite, but maybe I'm wrong.
     

    Attached Files:

  28. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    The D2dDestructibleSprite component requires a SpriteRenderer, so it cannot work with a normal canvas UI setup. If you don't need layout anchoring and other UI features then you may be able to combine them together as seen in your screenshot, but I imagine you will encounter issues with draw order. The 'correct' approach is a little complicated though:

    D2dDestructibleSprite extends the D2dDestructible class, which provides the 'core' of the destructible 2D features. D2dDestructible itself doesn't know anything about how its being rendered, so it's possible to extend this with a new component that is designed to work with UI Images and other graphics. However, this is a somewhat involved process that requires a lot of C# knowledge, and even if you manage it there will likely be compatibility issues with other D2D components. Most D2D components expect the destructible objects to be in '2D' thus flat on the XY plane in world space. However, a UI is usually in screen space, unless you specifically set it to work space. If you can use a world space UI then most of these issues are resolved. Another thing to keep in mind is that if you can use a world space canvas then it's also much easier to mix in SpriteRenderers and other standard 2D and 3D objects, so you may want to consider doing this to save a lot of headache. You could even use multiple canvases to work around any possible draw order issues.

    Let me know what you try and if you encounter any issues!
     
    Bit9Labs likes this.
  29. Bit9Labs

    Bit9Labs

    Joined:
    Mar 24, 2013
    Posts:
    9
    Aha thanks. Yes as a hobbyist I don't think learning your plugin and creating an extension is in my bailey-wick right now. I'll get creative in some other way for the time being, but thanks for the quick response.
     
    Darkcoder likes this.
  30. kharnite

    kharnite

    Joined:
    May 12, 2013
    Posts:
    1
    Hey @Darkcoder, first things first, absolutely stunning asset!
    I'm having trouble replicating shader code in Shader Graph using HDRP pipeline (no clue whether it's even relevant for discussion), since i'm not much of a shader guy yet...The scriptable toggle - hardcoded SRP shaders - work perfectly, but I need to replicate alpha masking in the graph since the shader is doing more other stuff...Don't you happen to have Shader Graph version lying around?
     
  31. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    I'll send you a private message with a new version. Apparently _AlphaTex is a reserved keyword in SRP, so I have to change some code to make this work.
     
  32. MTTHKL

    MTTHKL

    Joined:
    Aug 12, 2018
    Posts:
    5
    @Darkcoder, thanks for the asset. I think I'm in a similar situation as xSNOWM4Nx. - I've a procedurally generated 2d cave (700-1000 sprites including basic shapes to build the map, 16x16 pixels each sprite). Without making the sprites destructible, the FPS in editor remain at about 200, whilst making them destructible the FPS drops down to 50. The optimization options does not seem to improve the performance. Would you have any suggestions how to deal with this?

    Also, would you know why a moving object with D2D Explosion component sometimes randomly go through a surface of a destructible sprite and makes a hole there, whereas most of the time it works correctly.
     
  33. Raikir-i-sh

    Raikir-i-sh

    Joined:
    Aug 9, 2018
    Posts:
    13
    Bro, I was thinking of buying your asset. But I have a quesiton? Does It support .psb file skeletal animation ? I won't be using any sprite swap for animation but my question is .psb files makes sprite atlas automatically ( which is quite convenient) and I don't want to unpack the prefab and manually setup the skeletal animation. Does it work for this kind of system ?
     
  34. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Hey everyone,

    Version 3.0.9 of Destructible 2D is now out!
    • Moved main build to Unity 2018.4.13f1.
    • Added support for the new input system.
    • Added Fixed Joint demo scene.
    • Added Damage Threshold demo scene.
    • Added Intermediary Joint demo scene.
    • Added D2dFixtureJoint component.
    • Added D2dDamage.Threshold setting.
    • Updated demo scenes to use touch controls.
    • Fixed UI buttons not working in example scenes.
    • Fixed D2dPolygonCollider collider generation in some scenarios.
    • Changed D2D shader properties to avoid SRP clashes.
    • Rewrote D2dEdgeCollider.
    • Renamed D2dEdgeCollider.Straighten to Optimize.


    Sorry for the late reply! In this scenario I recommend you use traditional tile based destruction (e.g. the tile changes to a damaged look when hit, and is eventually removed), and reserve Destructible 2D sprites for important game pieces where tiles alone aren't sufficient. Destructible sprites have more overhead than traditional sprites, so it's not practical to use so many. If you really need to then you should use normal sprites and convert them into destructible ones only when the user does something that would require their destruction, and even then you should implement some code to auto destroy them or similar once you reach a certain number depending on the minimum device specs you want to target.

    Unlike normal sprites, destructible sprites can have any visual state (you can damage any pixel), and they also require more complex colliders, so they require more draw calls, and will never run as fast as normal sprites which are basically the same thing copied many times.


    Destructible 2D only works with SpriteRenderer objects. If you have a psb importer that can spit out SpriteRenderers that are configured as you expect, then it should be possible to make them destructible.
     
  35. roboroo

    roboroo

    Joined:
    Mar 27, 2017
    Posts:
    15
    Hi, thanks for your great Unity asset and all the helpful documentation included. Is there a way to limit the amount of clones the slicer makes? I've tried counting the width and height or the pixel amount to constrain that way but it does weird things to the image for some reason.
     
  36. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    The best way is to use the D2dRequirements component to somehow change your sprite (e.g. enable the D2dDestructibleSprite.Indestructible setting) when the AlphaCount goes below your desired threshold value. This is similar to how the Dynamic Destructible preset works, which you can see in the "Asteroid Blaster" demo scene.

    The problem with limiting the amount of slices is that this only works well if you do large slices. In my testing small slices would often result in there still being large chunks of sprite left in the scene, which look like they should be damageable/slicable, but because the slice limit had been reached, they just remained there which looked weird, so I implemented D2dRequirements to solve this.
     
  37. roboroo

    roboroo

    Joined:
    Mar 27, 2017
    Posts:
    15
    Thank you for the info and the quick reply, implemented something along those lines and got it working.
     
    Last edited: Jan 22, 2021
    Darkcoder likes this.
  38. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Hey everyone,

    pixels.gif

    Here's a new feature I've been working on. This allows you to detect which pixels were destroyed, and in this case spawn a particle there.

    This will appear in the next version, which is coming out soon :)
     
  39. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    13
    I was just about to message you on the forum and say that I couldn't find the component
    D2dModifiedPixelParticle listed in the documentation and you post the above :D

    One question I have is about unitys new 2d lighting system, is there a shader compatible with the system or should I just modify one?

    As with your Space Graphics Toolkit which seems to make its way into all my projects, this asset sets a standard above that of most assets on the store I commend you for that, your hard work certainly shows.

    I would recommend implementing more standard controls for your demos, I think I understand the drag method which might work better on mobile devices but I think just having movement relative to the character rather than the drag start position would make more sense and be easier to control. I have my own controllers but I think it might make your demos more approachable for new users. M

    Many Thanks.
     
  40. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    13
    Have you tried setting the rigidbody2d setting 'Collision Detection' of your bomb to continuous rather than discrete, this means it will never pass through a collider no matter how fast its going.
     
  41. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Hey everyone,

    Version 3.0.10 of Destructible 2D is now out!
    • Added D2dDestructibleSprite.MonitorPixels setting.
    • Added D2dDestructibleSprite.OnModifiedPixels event.
    • Added D2dDestructibleSprite.OnGlobalModifiedPixels event.
    • Added Monitor Pixels demo scene.

    Enjoy :)



    There are 2 modified lit shaders on the previous page, you can try them out. Let me know if neither of them work so I can update it!

    Regarding the controls, this was done to simplify the code since Unity introduces the new InputSystem, and writing the same code twice is annoying. To improve flexibility I want to make a more modular system, but that will have to wait a bit!
     
  42. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    13
    @Darkcoder fantastic thanks, I'll test the lit shaders and let you know! The modified pixels works great, it would be really nice if the system spawned particles the same colour as the pixels being removed from destructible sprite, I enabled collisions and gravity to the particle system and it looks so great, might be a bit performance hungry on your demo but I generally use highly optimised d2d objects. Again great product i'll make sure to write a review on this and Space graphics toolkit.
     
  43. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    13
    @Darkcoder hmm, I did a very quick test using the v2 shader posted on the previous page, it didn't seem to show the destruction on d2d objects. Should I be using the Alpha with White RGB Channels?
     
  44. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    I wanted to make the particles match the pixel colors, but the challenge is that this data isn't always stored in the sprite, and it's not always possible to quickly read the color. It could work if you use FullRGBA with a shader that only uses alpha, but then you couldn't have scorch marks unless your shader only uses the RGB from the AlphaTex, but then optimizing the sprite would lower its color resolution too.


    Did you try my shader or the one posted after? The latter may be more up to date. Yes Alpha with White RGB should be good.
     
  45. roboroo

    roboroo

    Joined:
    Mar 27, 2017
    Posts:
    15
    Experiencing a bug in Unity 2020.2.2 where trying to change the D2d destructible sprite image in a prefab in the scene freezes the editor and has to be shut down via task manager.
     
  46. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Can you describe exact steps to replicate this?

    If I open a demo scene like "Asteroid Blaster", drag one of the asteroids into the Project to make it a prefab, double click the prefab, then I can change the D2dDestrucribleSprite.Shape or SpriteRenderer.Shape without issue.

    This is in 2020.2.1f1 at least.
     
  47. thorgaming_42

    thorgaming_42

    Joined:
    Sep 25, 2015
    Posts:
    13
    @Darkcoder
    I was using the one after yours, the lighting etc works correctly just the destruction does not appear on the sprite, so the one you posted before is for the lightweight render pipeline? I'll have a look into this one and the problem, haven't had much time to investigate recently. Thanks
     
  48. roboroo

    roboroo

    Joined:
    Mar 27, 2017
    Posts:
    15
    I can confirm, going into the demo scene and making a prefab of the split-able beam and then trying to change the sprite by clicking on it and opening the select sprite window, causes the freeze. I use Playmaker but even with no FSM on the prefab it still freezes (see image). Hope this helps
     

    Attached Files:

  49. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Alright, I've updated the shader to work with the latest URP and attached it to this post :)


    Can you test this in a new project or using just the example D2D scenes and tell me exactly step by step what I must do to replicate this? As I said, I tested this in a new project and was able to make a prefab and modify the prefab's sprite and destructible sprite shape without issue, so there must be some steps I'm missing.

    [Edit] The shader file below is for D2D Version 3.0.8 and earlier.
     

    Attached Files:

    Last edited: Feb 18, 2021
  50. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Oops, the previous shader works for Destructible 2D 3.0.8 and earlier.

    The shader attached to this post should be suitable for 3.0.9 and beyond. However... in my testing it doesn't seem to work for some reason, and strangely causes the demo scenes to break. I'll have to test it a bit more to see what's going on, maybe my project is corrupted or something... hmm

    [Edit] Obsolete shader file deleted, see below for the latest!
     
    Last edited: Feb 18, 2021