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

Simple Fracture Script [v 1.01]

Discussion in 'Made With Unity' started by •BTM, Aug 20, 2010.

  1. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    [9/09/10] : Version 1.01
    Small update concerning Destroy Small After Time and the placement of the center of gravity of fractured objects.

    [7/09/10] : Version 1.0
    I've uploaded a first version of the script with a few more features than in the demo, including minimum dimensions and the ability to split jointed objects with realistic results (the joints are connected to the part they should be after breaking).




    Try the demo (outdated) if you want.



    Notes :

    The biggest problem with this script right now is the way it 'breaks' objects; it clones the object, finds a plane based on user variables, and flattens all the points on the other side of the plane onto it, then repeats this with the clone and the other side of the plane. This way of doing things can lead to several different problems, mostly visual.

    This method isn't truly splitting the object, has bad effects on concave objects and textures, and also limits what else I can do with it.
    The only real solution I can think of would be writing a new script that would work more like the boolean modifier in blender (and probably other modelers). If I did manage to make a boolean-type way for splitting the objects, It would open a lot of opportunities that could lead to an actual procedural destruction script. :) Unfortunately, any way of truly dynamically breaking an object would be really slow, so I haven't bothered with it at all. :?


    To call fractures from a script :
    Code (csharp):
    1. SimpleFracture.FractureAtPoint(point : Vector3,force : Vector3)
    Settings:

    Fracture To Point : if enabled, the geometry will not be 'flattened' to the plane, but be moved to a single point on it, based on the average vertex position. The results aren't that nice, but it's a lot faster and eliminates most odd flattening effects from concave objects.

    Total Max Fractures : The maximum amount of times an object can be divided. If it's 1, it will split into a max of 2 pieces. If it's 2, it will have 2 iterations of splitting at the most, so it will split into a max of 4 pieces. 3 is a max of 8 pieces, etc.
    Every time the object is split, this number goes down by 1 for each piece, until it reaches zero.

    Force Per Division : The amount of 'force' it takes for each division to occur. If you have a max of 3 divisions, and this is 20, then it will mean that any collision with a force bigger than 20 will split it into 2, over 40 into 4, and over 60 into 8 pieces.

    Min Breaking Force : The minimum force required for the object to fracture. Objects won't be fractured unless the collision 'force' is higher than this AND force per division. Example of use: if Force Per Division is 1, max fractures is 4, and this is 30, then any collision with a force < 30 will not fracture it, and anything higher will fracture it into 16 pieces.

    Max Fractures Per Call : If this is smaller than Total Max Fractures, it is the maximum amount of fractures the object can be split into by a single collision.

    Random Offset : The splitting plane from a collision is always on the point of collision (or center of the object, if Fracture At Center is true). However, when this value is higher than 0, it will move the splitting point by this value multiplied by a random InsideUnitSphere multiplied by the mesh's bounds.

    Min Fracture Size : If any of the dimensions of the mesh's bounding box are smaller than the dimensions specified here, the object will be considered 'too small' to split, and the max fractures it can undergo is changed to 0. This can be useful for things like shards of wood: if you set max fractures to a very high number, the only thing stopping the objects from splitting is this.

    Grain : The splitting plane of this script splits geometry on a plane with a random vector multiplied by this vector. If this vector is 0,1,0, then the splitting plane will always be on the xz axis (that is, the normal will always be on the z axis). If this is 1,1,0, then the z value of the plane's normal will never be higher than 0; this means that it will only split in 2 dimensions, like a window breaking.

    Use Collision Direction : Between 0 and 1. If this is set to 1, then the normal of the splitting plane will always be perpendicular to the relative velocity of the collision. The closer to 1 this is, the closer to being perpendicular to the relative velocity the splitting plane will be. (I'm bad at explaining these things, sorry.)

    Fracture At Center : If true, the object will fracture at it's center instead of on the collision point. Good for getting things to blow up, etc.

    Smart Joints : If there is a joint component in this object and/or if this object is jointed by another object, whatever side of the plane the other body is on will still be connected, while the piece on the opposite side will be disconnected. If this is not on, all joints connected to the object in any way are eliminated upon breaking.

    Destroy All After Time : If this isn't 0, it's the time after the first fracture until all objects are destroyed. The collider of the objects is destroyed 1 second before this, so that they don't seem to just disappear instantly.

    Destroy Small After Time : If not 0, this is the time after the final possible division of an object until it is destroyed. The collider of the objects is destroyed 1 second before this, so that they don't seem to just disappear instantly.

    Instantiate On Break : This will be instantiated the first time the object is broken.

    Total Mass If Static : If the object is static, then all it's pieces become rigidbodies after splitting. What THIS value does, is define the total mass of the object before it splits, if it doesn't have a rigidbody attached. (Each time a piece splits, it's mass is divided in half in each piece.)

    If you need any more info, you can take a look at the code or send me a PM, I'll try to respond as often as I can.
     

    Attached Files:

  2. WarpedAxiom

    WarpedAxiom

    Joined:
    Oct 27, 2006
    Posts:
    245
    ... why are you so awesome?
     
  3. rouhee

    rouhee

    Joined:
    Dec 23, 2008
    Posts:
    194
    This was fun! :D

    Just noticed that player can fly on the stuff it collects, jump by jumping on it. :D
     
  4. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
    I tried to do such thing too : http://www.indiedb.com/games/sawyer
    Before this demo I tried to make sword slicing but I could not split mesh diagonally. I used bounds and vertices above that bound was flattened, same principle as your code. I had calculated angle and aligned splitter cube to that angle unfortunately bounds have always same position it doesn't rotates and only bounds have contain function. It would be great if colliders have contain function.
    Such style isn't true splitting and if you cut human, you have many unnecessary plys and vertices pushed together, but I think may be such style will be more fast than procedural splitting, because you must create new vertices, triangles and uv arrays and in our style we copy already filled arrays.
     
  5. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
    You have used this liar splitting very well. :D
    I noticed that it can't cut some directions??
     
  6. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
  7. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    It can cut in any direction, but it also has a grain variable. The script cuts along a plane that goes through the point of contact (or center of the object if you check that setting, like the rocks in the example), and has a random normal. this normal is a random inside sphere vector, multiplied by a grain vector. what the grain variable does is let the user define in what direction they want the object to be sliced in more or less often. for example:

    The glass has a grain of (1, 1, 0). This means that it will never split width-wise, but is just as likely to split in any other way.

    the wood has a grain of (0.03, 1, 0.001). This means it will split way more one way than any other way. In this case, it splits width-wise, and the planes are still rotated slightly at random.
     
  8. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
    How are you flattening vertices diagonally?
    I used bounds, on main object all vertices Y on top of the splitter cube's bound was decreasing and if it was in splitter cube's bound it stopped, on copied object everything was done contrariwise.
     
  9. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    I use a plane (which can face any direction), and plane.GetSide.
     
  10. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
    and you increase or decrease vertices Y as I'm doing?
     
  11. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    I move them toward the plane with
    Code (csharp):
    1. vertsA[i] -= plane.GetDistanceToPoint(vertsA[i])*plane.normal;
     
  12. temo_koki

    temo_koki

    Joined:
    Jul 14, 2009
    Posts:
    308
    Wow, the plane is amazing, I didn't know this :)
     
  13. jedy

    jedy

    Joined:
    Aug 1, 2010
    Posts:
    579
    Awesome script! Add some flames and it will be the coolest explosion system available.
     
  14. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    No flames, but I'm adding explosions to the example soon :)
     

    Attached Files:

  15. jedy

    jedy

    Joined:
    Aug 1, 2010
    Posts:
    579
    Can't wait to see that
     
  16. WinningGuy

    WinningGuy

    Joined:
    Aug 10, 2009
    Posts:
    884
  17. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    First version of the script is up. If there are any problems with it, feel free to let me know.
     
  18. coin-god

    coin-god

    Joined:
    Jan 21, 2010
    Posts:
    325
    Awesome! Downloading.
     
  19. mikesgames

    mikesgames

    Joined:
    Apr 16, 2010
    Posts:
    1,071
    this rocks!

    Now I can make some explosions look awesome!
     
  20. Neodrop

    Neodrop

    Joined:
    Oct 24, 2008
    Posts:
    1,359
    Thanks a lot. Very smart script.
     
  21. JP

    JP

    Joined:
    Aug 26, 2010
    Posts:
    21
    All I can say is WOW! that's sweet!
     
  22. Hogfather

    Hogfather

    Joined:
    Aug 17, 2010
    Posts:
    44
    You sir, have my outmost respect
     
  23. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    Just made a little update that recalculates the center of mass to the center of the mesh's bounding volume, and also fixes an issue with Destroy Small After Time.
     
  24. angel_m

    angel_m

    Joined:
    Nov 4, 2005
    Posts:
    1,160
    Very good!
    Thanks.
     
  25. scinfu

    scinfu

    Joined:
    Oct 23, 2008
    Posts:
    404
    awesome, thanks.

    which version of Unity you use?

    In 2.6.1 i have this error

    EDIT : Solved .
     
    Last edited: Sep 26, 2010
  26. fosion

    fosion

    Joined:
    Jul 20, 2010
    Posts:
    6
    Hello Everybody,

    first of all great work, its really fun to destroy things, one my dreams since i played videogames on my amiga i dreamed of realtime destruction...

    one good approximation for the fractures would be a delauney triangulation in 3D, not that i think coding this is fun 8).

    http://www.cs.cornell.edu/Info/People/chew/Delaunay.html
    http://en.wikipedia.org/wiki/Voronoi

    Rayfire in Max uses this
    http://www.youtube.com/watch?v=1FTP3BlWtaU

    I hope you are our hero and you will get it done.

    cheers Franky
     
    Last edited: Sep 28, 2010
  27. SomebodyZA

    SomebodyZA

    Joined:
    May 8, 2010
    Posts:
    168
    Hay there I was just wondering if you Fracture script works on Spheres.Because I would realy like to follow up on your idea for using it in SolaSim.:confused:

    Also would it cost us.If so what's the fee or could we just strike some kind of deal.:cool:

    Regards: BrightNewWorlds[Jason van der Meijden]
     
  28. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    Hey everyone; I'd just like to say a few things.

    First: The update to the forum changed the file name of SimpleFracture.js to simplefracture_163.js, though I don't know why. Make sure to change it to SimpleFracture when using it in a project.

    Second: I have yet to try the script with unity 3, but I'll get around to it.

    Third: A voronoi pattern of splitting may work, but I think it would be slower, and the current method acts in a way I personally like more.

    Fourth: My script works only with mesh colliders.

    if any other type of collider is split, it will break, but the colliders on the pieces will be destroyed, and then the pieces themselves will be destroyed shortly after.

    Because of this, I wouldn't suggest using it with spheres. If you make your own, low-poly spheres, you could make them convexhulls, and then it would work.

    Fifth: I'm going to update the script some time soon.
     
  29. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    I've tried the script with Unity 3, and it seems to work fine, for the most part.

    One thing I'm changing is the setting of the center of mass; The new scripting reference explained that the position of the center of mass does not take into account scaling. Now that I know this, I'm changing the script so that it fixes some issues with its placement, and makes things fall apart much better. I'm going to look through the API some more before uploading a new version though, to see if there are any other improvements I can make.

    One last thing, in Unity 3, I seem to get an error with the script sometimes, but I don't fully understand what's going on. Anyone have any ideas? (see image)
     

    Attached Files:

    Last edited: Oct 1, 2010
  30. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    This may seem a bit odd, but I'm posting now to see if anyone could give me an idea of what might cause the above error, as it needs to be fixed before I can make a functional version for 3.0. Whatever object causes the error will usually not be able to split afterwards, and it seems to have an effect on performance too. I never got this error in 2.6, so I'm kinda stuck on what to do about it. I get the error in many different circumstances , but mostly when destroying mesh colliders with the script.
     
  31. oblivionfeet

    oblivionfeet

    Joined:
    Jul 24, 2010
    Posts:
    481
    Can't help with your error, just wanted to say what a great idea this is, and hope I can find an excuse.. I mean reason, to use it on something! :D
     
  32. Reapazor

    Reapazor

    Joined:
    Jun 19, 2008
    Posts:
    173
  33. Reapazor

    Reapazor

    Joined:
    Jun 19, 2008
    Posts:
    173
    Just a heads up ... looks like the issue is directly related to how the colliders are being deleted slightly before the gameobject. Removing that part remedies all of it.
     
  34. friken

    friken

    Joined:
    May 1, 2009
    Posts:
    84
    Thanks for the script. Very cool stuff. I'm attempting to get it to fracture an object where each chunk is the full z depth of the original object. To describe, imagine a fixed orthographic camera looking at a cube. The new 'chunk' on fracture would have identical shape on the front and back side of the object, like a puzzle piece. Any ideas how to modify it to do this?

    Thanks
     
  35. bgivenb

    bgivenb

    Joined:
    Sep 15, 2010
    Posts:
    449
    wow, I am so using this!
     
  36. bgivenb

    bgivenb

    Joined:
    Sep 15, 2010
    Posts:
    449
    Could you give some example prefabs of like the rocks and glass? I'm having trouble perfecting a window to look right, and I would help to see how you set up yours. Thank you, and btw your the best!
     
  37. pixelsteam

    pixelsteam

    Joined:
    May 1, 2009
    Posts:
    924
    Fantastic Script and I really like your game demo...
     
  38. •BTM

    •BTM

    Joined:
    Jun 6, 2010
    Posts:
    108
    I think I know what you're saying, and I'd suggest making the grain of the object (1,1,0). This will make it so that it will never cut along the z direction, unless 'use collision direction' is bigger than zero.

    I've been changing the script lately, and I'll probably release a new version soon (although I'm not sure how soon). I've added and changed some things, but I'm still having problems with the reliability of deciding what part of an object keeps a joint (with smart joints), as well as the couple of errors it returns some times. I'll try to get those eliminated, if possible. I'll also write a bit of documentation and make a couple example prefabs when I upload a new version.
     
  39. KillerSneak

    KillerSneak

    Joined:
    Jan 9, 2011
    Posts:
    38
    Very cool, I will certainly make use off it with the project I'm working on (fps)
     
  40. KillerSneak

    KillerSneak

    Joined:
    Jan 9, 2011
    Posts:
    38
    I can;t get it to work with Unity 3.1


    Assets/Misc Scripts/simplefracture.js(134,96): BCE0005: Unknown identifier: 'SimpleFracture'.

    Thats the error, and this is the piece of code where the error leads

    // smartjoints will allow joints to function properly.
    if (smartJoints) {
    jointsb = GetComponents(Joint);
    if (jointsb){
    // Basically, it goes through each joint and sees if the object A or B are closer to the connected body. Whichever is closer keeps the joint.
    for (i=0;i<jointsb.length;i++){
    if (jointsb.connectedBody != null plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb.connectedBody.transform.position))) {
    if (jointsb.gameObject.GetComponent(SimpleFracture).joints) {
    // If we're attached to a fracture object and the new object is closer, switch the connected object's joint variable at the correct index.
    for (c in jointsb.gameObject.GetComponent(SimpleFracture).joints) {
    if (c == jointsb) {c = newObject.GetComponents(Joint);}
    }
    }
    Destroy(jointsb);
    }
    else {
    Destroy(newObject.GetComponents(Joint));
    }
    }
    }
    // joints contains all joints this object is attached to. It checks if the joint still exists, and if the new object is closer. If so, changes the connection. It then removes the joint from the joints variable at the correct index.
     
  41. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,350
    *
     
  42. AbovegroundDan

    AbovegroundDan

    Joined:
    Jan 16, 2010
    Posts:
    4
    @KillerSneak - Looks like you need to rename your script from simplefracture.js to SimpleFracture.js. Otherwise the GetComponent will fail.
     
  43. KillerSneak

    KillerSneak

    Joined:
    Jan 9, 2011
    Posts:
    38
    Thanks and sorry for my late reply I already figured that and have been working with this awesome script. It's making blowing up things much more fun :)
     
  44. Udyrfrykte

    Udyrfrykte

    Joined:
    Feb 14, 2010
    Posts:
    156
    I'm a slow dude, so I have a problem:

    Are the fractures supposed to have colliders? Seemingly they do in the demo, but when an object (a simple door) is fractured in my project only a single fracture contains a collider.

    Anyhow, if I can get it working or not (I'll just script it myself), this thing is amazing. I didn't think this was possible in Unity!
     
  45. KillerSneak

    KillerSneak

    Joined:
    Jan 9, 2011
    Posts:
    38
    I'm very interested to see what settings you used with the script, would it be possible for you to post your settings for each of the breakable objects?

    -Tiles
    -Wood
    -Glass

    I did get it working some what, but it looks no where near the demo you posted that looks stunning.
     
  46. nath0rn

    nath0rn

    Joined:
    Sep 25, 2010
    Posts:
    5
    This is really cool! Although I noticed that if the breakable object is in a parent, it wont break at all... !

    otherwise it works great. very cool stuff !
     
  47. Kinos141

    Kinos141

    Joined:
    Jun 22, 2011
    Posts:
    969
    This is a great tool. You should shoot this to Unity designers so it can be added to future Unity updates.
     
  48. rockysam888

    rockysam888

    Joined:
    Jul 28, 2009
    Posts:
    650
  49. asnane

    asnane

    Joined:
    Nov 23, 2010
    Posts:
    8
    it's very useful. thanks a lot.
     
  50. clockwork_fromage

    clockwork_fromage

    Joined:
    Aug 2, 2011
    Posts:
    13
    hi , your code is amazing mister ,a great for learning how to handle meshes too altough im getting an error from it ,
    the line # 191
    newObject.GetComponent(SimpleFracture).Fracture(point,force,iterations);

    Definition of 'SimpleFracture.Fracture' depends on 'SimpleFracture.Fracture' whose type could not be resolved because of a cycle. Explicitly declare the type of either one to break the cycle.

    apparently fracture is called within itself and i cant really figure out any workaround
     
    Last edited: Aug 6, 2011