Search Unity

Sprite Slicer - 'Fruit Ninja'-style sprite cutting system

Discussion in '2D' started by mrsquare, Nov 20, 2013.

Thread Status:
Not open for further replies.
  1. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Hi folks,

    I've posted this in the main Asset Store section, but though it would be worth reposting here too, seeing as its directly relevant to people that might frequent this bit of the forum. Hope that's okay!

    Anyways, I'm pleased to announce the release of Sprite Slicer on the Unity Asset Store :)


    Web Player Demo

    Tutorial Video

    Sprite Slicer allows you to cut any physics enabled sprite into little pieces, each of which then behaves as its own independent physics object. Its perfect for bringing your 2D game to life with destructible objects and environments, or for creating a Fruit-Ninja style cutting game.

    * Works on both Unity and 2D Toolkit sprites.
    * Simple static script functions allow you to slice sprites along a given line, or explode them into multiple parts.
    * Optimised to preserve dynamic batching and reduce draw calls.
    * Slices any sprite with a 2D box, circle or convex polygon collider
    * Full C# source code and example scene included


    The code has been designed to be as transparent as possible - there are no new gameobjects to create; you simply pass a cut start and cut end point to one of the static Sprite Slicer functions, and the code will handle the rest. Once cut, each child sprite behaves as its own separate physics body, retaining all the physics and rendering properties of the parent object, and can itself be cut into further child objects. If required, the slicing functions can return a list of all the cut objects along with their child objects and cut positions, so that the user's code can perform additional processing once the cut has taken place. Equally, you can delay destruction of the parent object in the event that you need to access variables from it before it is destroyed.

    Screenshots




    I hope this proves helpful to some people out there! Please feel free to reply in this thread or PM me if you have any questions :)
     
    Last edited: Dec 4, 2013
  2. Kurius

    Kurius

    Joined:
    Sep 29, 2013
    Posts:
    412
    Awesome! :D
     
  3. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Some guys over on Reddit were asking for some example of the interface, so this might be of interest to some folk here too:

    Code (csharp):
    1.  
    2. static void SliceAllSprites(Vector3 worldStartPoint, Vector3 worldEndPoint);
    3. static void SliceAllSprites(Vector3 worldStartPoint, Vector3 worldEndPoint, bool destroySlicedObjects, ref List<SpriteSlicer2DSliceInfo> slicedObjectInfo);
    4. static void SliceSprite(Vector3 worldStartPoint, Vector3 worldEndPoint, GameObject sprite);
    5. static void SliceSprite(Vector3 worldStartPoint, Vector3 worldEndPoint, GameObject sprite, bool destroySlicedObjects, ref List<SpriteSlicer2DSliceInfo> slicedObjectInfo);
    6.  
    So you have the option of slicing any sprite that intersects the vector or you can pass through a specific gameobject if you know exactly what it is that you want to cut. The demo is using the first option, which is why you can get multiple things getting cut if you move the mouse fast enough.

    SpriteSlicer2DSliceInfo is an optional parameter, which will get filled out with information on which slice generated which child objects from which parent object, so you can do any extra processing as required (eg. add particle effects at the cut positions, increment a score depending on what type of object the parent was)

    The explosion code is as follows:

    Code (csharp):
    1.  
    2. static void ExplodeSprite(GameObject sprite, int numCuts, float explosionForce);
    3. static void ExplodeSprite(GameObject sprite, int numCuts, float explosionForce, bool destroySlicedObjects, ref List<SpriteSlicer2DSliceInfo> slicedObjectInfo);
    4.  
    It basically slices the object multiple times at random angles through the centre, and then applies an outward force to each child object away from the centre. I've got some ideas for improving this - specifically running a triangulation algorithm over the mesh and then creating the child objects from that. Should make a more pleasing shattering type effect with more evenly distributed polys (its a bit 'chunky' at the moment).
     
  4. jgalvezpa

    jgalvezpa

    Joined:
    Dec 27, 2012
    Posts:
    36
    Hi hey are you interested to port it to playamker by creating custom actions?
     
  5. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Does this only working on certain planes/orientation?
    If the sprite is rotated, say 270 X, will it work?
    What if the background/game orientation is on the XY plane, and the sprite is rotated 90 degrees to appear to be 'standing up'?
    Does it just use the sprites relative position/rotation and work from there (I'd hope it does.)
    Do you need any specific shaders on the sprite?
    Can you specify how many parts an 'exploded' sprite will create, or declare a range for max/min?
    Can you slice a sprite that has been sliced that was sliced?
     
  6. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Heya - possibly, if there is enough interest! I haven't used Playmaker before, so I'd need to purchase a copy, but would definitely look into it if there was demand.

    Heya

    - Yep, it assumes a standard 2D X/Y orientation. I gave it a try just now with a sprite rotated around the X axis so its facing out of the screen towards the camera and it didn't seem to register the slice correctly (I'm not quite sure why you'd have this situation though - are you doing Doom-style 2D sprites in a 3D environment or something?)
    - Yes - the slices translate raycast world coordinates into local sprite coordinates and work from there.
    - Nope, no specific shaders needed. There is literally no setup required - just call one of the static Sprite Slicer functions and it'll work.
    - Yep, you can define the number of cuts an explosion should make - the code then slices the object this number of times through the centre before applying an outwards force.
    - Yes, you can slice sprites as many times as you like, even sprites that have already been sliced.
     
  7. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
  8. Yukichu

    Yukichu

    Joined:
    Apr 2, 2013
    Posts:
    420
    Not quite Doom, but more like 2.5D game using 2D sprites 'standing' up on their axis, with screen rotation so often the sprites have changed their rotation as well to face the camera.

    Well, very slick for a pure 2D game. I'll keep it on my watch list should I ever need it (or it goes on sale ;)
     
  9. aliozan

    aliozan

    Joined:
    Nov 18, 2013
    Posts:
    9
    i bought 2 hours ago i need concave collider support :D is it possible?
     
  10. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Heya - the algorithm can split concave colliders, but it depends on how you are cutting them.

    The main reason that they are not supported is because the code is not guaranteed to cut them properly in all situations. Eg. If you have an 'E' shaped collider, and slice it vertically down the middle, you will end up with 4 separate polygons (the main body and then the 'tips' of each horizontal line) - the algorithm is only designed to split polygons in two, so this outcome is unexpected.

    I'll submit an update tonight to allow you to enable concave polygon collider slicing if you really need it, but you'll need to be aware that it might cause odd results if you slice an object in such a way that > 2 child objects will need to be generated as a result.
     
  11. aliozan

    aliozan

    Joined:
    Nov 18, 2013
    Posts:
    9
    Thank you to answer. Just i wonder: if i have an 'E' shaped collider and slice it down the middle. in this stuation i can call in order the slice function, slice to two piece the entire shape each time. i mean i think not necessary slice at a time entire shape. Just it must be in order. By the way this code already awesome. It is cheap. Worth every penny. Thank you again. (sorry for bad english.)
     
  12. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Hm - maybe not, actually. Using an 'E' shaped concave collider, and also a concave version of the banana in the demo project, I get this:

    $Before.png
    $After.png

    So you can see that it copes with the banana a lot better - there is a little bit of weirdness around the top bit of the mesh (near the stalk), but apart from that it is generally okay, whereas the 'E' doesn't really work at all. It might be down to the increased number of vertices in the banana, or just the fact that it is less concave, I'm not sure.

    I'd definitely like to support concave polygons, unfortunately its not very straightforward to implement - I'll keep looking for a solution though and can hopefully update the package once I've worked something out :)
     
  13. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    By the way, for anybody who downloaded this last month, its well worth upgrading to the latest version of the asset.

    Unity have now fixed their bug with not being able to alter 2D mass via script, so I've updated the Sprite Slicer code to properly calculate the relative mass of the sliced objects - little chunks will now be much lighter than big chunks, essentially, so their behaviour is much more realistic. The web demo (link in the first post) has been updated to include this - slicing things up looks much more natural (and more chaotic!) now.
     
  14. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    The 1.13 update has just gone live - many thanks to Steve H, who spotted a bug in the explosion code that was limiting the max number of child objects that could be generated. Explosions should now work much better (as can be seen in the Web Demo) :)
     
  15. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Just to answer a question on the Youtube channel (since the code formatting is better on here!)

    In the code where you are exploding the sprite, do this:

    Code (csharp):
    1.  
    2. // First create a list of SpriteSlicer2DSliceInfo's
    3. List<SpriteSlicer2DSliceInfo> slicedSpriteInfo = new List<SpriteSlicer2DSliceInfo>();
    4.  
    5. // Now explode or slice the sprite, passing in the SpriteSlicer2DSliceInfo list
    6. SpriteSlicer2D.ExplodeSprite(blah, 32, 8000.0f, true, ref slicedSpriteInfo);
    7.                    
    8. // We can now loop through all the sliced sprites...
    9. foreach(SpriteSlicer2DSliceInfo sliceInfo in slicedSpriteInfo)
    10. {
    11.     // And loop through all the new gameObjects that were been created as a result of the slice operations...
    12.     foreach(GameObject childObject in sliceInfo.ChildObjects)
    13.     {
    14.         // ...and tell Unity to destroy the sprite after two seconds
    15.         Destroy(childObject, 2.0f);
    16.     }
    17. }
    18.  
    Hope that helps :)
     
    Last edited: Feb 15, 2014
  16. Tony_B

    Tony_B

    Joined:
    Feb 5, 2014
    Posts:
    8
    Alternatively:

    Code (csharp):
    1. Destroy(childObject, 2.0f);
     
  17. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Hah - didn't know you could do that! Thats handy, thanks :)

    *edit* Updated the original answer
     
    Last edited: Feb 15, 2014
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, duplicate topics aren't allowed, sorry. Please use the topic in the asset store section.

    --Eric
     
Thread Status:
Not open for further replies.