Search Unity

[Released] Sprite Mask - masking system for Unity Sprite

Discussion in 'Assets and Asset Store' started by PoL231, Jan 21, 2015.

  1. detournment_19

    detournment_19

    Joined:
    Jan 20, 2015
    Posts:
    22
    Thanks, finally got it working. Had some problems loading the sprite (needed typeof), and then had to change the import settings on the texture to 1 PPU instead of 100. Working great now.
     
  2. detournment_19

    detournment_19

    Joined:
    Jan 20, 2015
    Posts:
    22
    One other thing. I have sprites that I add inside the mask at runtime, but then the user is allowed to drag them around. While dragging I'd like them to not be masked, and then return to being masked when they let go. When the move starts, I change the parent transform of the dragged object to another object that is not in the hierarchy of the masked sprite, but it is still being masked, even after calling update on the SpriteMask component. Does something else need to be changed on the sprite being moved?
     
  3. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    The problem is, that in fact the material of SpriteRenderer decides that it is masked or not, and not the fact that it is outside of the SpriteMask hierarchy.

    One way to unmask the sprite is to disable masking on the SpriteMask, but that will cause all masked object to be unmasked.

    Second way is to restore your SpriteRenderer material to the default one. You can use Unity default material for SpriteRenderer or you can create your own material instance with 'Sprites/Default' shader.
     
  4. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi,

    SpriteMask will work with th2dSprite if his material shader supports Stencil buffer. SpriteMask can mask any Renderer whose material shader supports Stencil buffer.

    I hope this will help you.
     
  5. th3shark

    th3shark

    Joined:
    Apr 12, 2016
    Posts:
    2
    Hello. I just bought SpriteMask and I get can't some of the examples to work. On example 3, the Sprite mask, there's supposed to be a white square cut into the shape of a tree, correct? But I can't see the square or the tree.



    A similar problem happens with example 4, the texture mask. This is using Unity 5.3.1f1 personal. The option to enable the 24-bit depth buffer is missing from the player menu in this version, so it's possible the problem has to do something with that. What could the problem be?
     
  6. fenderrio

    fenderrio

    Joined:
    Mar 2, 2013
    Posts:
    147
    I'm also seeing the same problems as @th3shark above. Would greatly appreciate some info on how to get this working in Unity 5.3.4.
    Thanks in advance!
     
  7. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    I've just updated Unity to 5.3.4 and have the same problem. I will fix it ASAP.
     
  8. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    I've just updated Unity to 5.3.4 and have the same problem. I will fix it ASAP.
     
  9. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    After changing sorting order on 'bg' to value bigger than sorting order from 'Mask' (e.g. Order in Layer -> 1), it starts to work again. I don't know why did that happen after Unity update.

    Please let me know if this is helpful on your sides.

    screen.jpg
     
  10. th3shark

    th3shark

    Joined:
    Apr 12, 2016
    Posts:
    2
    This solved the problem! Thanks!
     
  11. CarinaMclane

    CarinaMclane

    Joined:
    Mar 12, 2014
    Posts:
    23
    Before buying this for an Android specific project - is this known to work / supported on Android? :)
     
  12. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Sorry for the delay, I didn't receive any notification email ... Of course SpriteMask works on Android. It works on any platform.
     
  13. pranavt7

    pranavt7

    Joined:
    Nov 3, 2014
    Posts:
    1
    I am using that mask on an object. I want to change the Size of the sprite mask object when I change the position of another object. Any idea how I could do this?
     
  14. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi pranavt7,

    It depends what kind of type on SpriteMask do you use. If you use "Rectangle" or "Texture" just resize it on runtime like followed:
    Code (CSharp):
    1. GetComponent<SpriteMask>().size = new Vectror2(yourSizeX, youSizeY);
    If you're using type "Sprite", changing size wouldn't work because of SpriteRenderer constrains.

    To react on position change you can use Transform.hasChanged. More info you can find here.
     
  15. nsfnotthrowingaway

    nsfnotthrowingaway

    Joined:
    Feb 18, 2016
    Posts:
    48
    I'm pretty lost. I have a few questions.

    1. Can I use this on a Quad with a Standard Shader? (the quad is the child needing to be restricted to the parent's mask) I created a copy of the Standard Shader with textures set for the Emission and Albedo components and I'm trying to use it for the material of the MeshRenderer of the quad.

    2. Sometimes when I add a quad as a child to the mask it automatically sets the first material of the MeshRenderer for the quad to the Sprite Mask. Sometimes it doesn't. If it doesn't, is there a way I can add it myself, so it has the default id set?

    3. Assuming I have the Sprite Mask material on the MeshRenderer, do I add a second material and make that the Standard shader copy I have, do I make the first material the Standard shader copy and keep the second the Sprite Mask material?

    It's usually all invisible, sometimes it creates a messed up mask where the transparent parts of my quad are turning the mask white, sometimes is makes my quad render normally as if it weren't in the mask.

    I get the same results whether I add a quad as a child to a mask in one of the examples, or if I start from scratch and create an empty object with a sprite mask.
     
    Last edited: Jun 16, 2016
  16. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi,

    If you are using DefaultResourcesExtra\Standard.shader, then this shader by default doesn't support Stencil buffer. That way SpriteMask tries to replace it with a default shader for Sprite's.
    I can help you to extend the this shader so it can work with Stencil buffer. This way it will proper work with SpriteMask.

    Cheers!
     
  17. krstrobe

    krstrobe

    Joined:
    Dec 3, 2015
    Posts:
    5
    I have some sprites being dynamically created with scripts, and they use the material slot to make the sprite, but I can't figure out how to make that sprite mask. Same problem I had with unity's built in mask script. it doesn't work with a material applied. Am I missing something? Does it not have this ability? Thanks.
     
  18. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi krstrobe,

    Are you using a custom material or the default one: Sprites-Default?
    How to create SpriteMask at runtime you can see on '05 - Runtime mask' scene in the Examples folder.
     
  19. krstrobe

    krstrobe

    Joined:
    Dec 3, 2015
    Posts:
    5
    Hi PoL231,

    I am using a custom material. it's the same material that is on scene objects. I'll try looking at the runtime example scene. Thanks for the reply. I'll let you know how it goes.
     
  20. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Does your custom material supports Stencil buffer? If not, then just look at point 5 'Can I use my own shader?' in the Readme.txt.
     
  21. krstrobe

    krstrobe

    Joined:
    Dec 3, 2015
    Posts:
    5
    I'm not sure, checking point 5! Thanks!
     
  22. iolloi

    iolloi

    Joined:
    Aug 11, 2016
    Posts:
    3
    Hi PoL231,

    I have a weird issue here: firstly I created a 2D empty gameobject, then added a child with sprite renderer, then added a chilld to the renderer as sprite mask (so mask is the child of child of gameobject). Everything works perfectly except when I changed the x-scale of main gameobject to -1, then rotate the renderer child, either the shape or rotation of sprite mask goes abnormal.

    I've tried rectangle and sprite type of mask and they all have this issue. Any chance to look into this please?
    BTW great asset, essential in 2d game, thanks a lot!
     
  23. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi,

    Does your hierarchy look like this?

    Code (CSharp):
    1. [GameObject] (empty)
    2.   + [GameObject]
    3.     <SpriteRenderer>
    4.       + [GameObject]
    5.         <SpriteMask>
    Are you masking the SpriteRenderer? By default, in this scenario, the SpriteRenderer isn't masked, becouse it isn't under its SpriteMask game object. I assume, you are using 'Masked object' feature. Am I right?

    This hierarchy doesn't work for me either.

    If you use this hierarchy:

    Code (CSharp):
    1. [GameObject] (empty)
    2.   + [GameObject]
    3.     <SpriteMask>
    4.       + [GameObject]
    5.         <SpriteRenderer>
    It works perfect without any problems.
     
  24. iolloi

    iolloi

    Joined:
    Aug 11, 2016
    Posts:
    3
    Hi,

    Actually I'm trying to achieve some sprite scale effect, to make some sprite be scaled inside the sprite. I didn't notice the sprite mask can show the sprite used for masking so my hierachy is like this:

    Code (CSharp):
    1. [GameObject] (empty)
    2. + [Gameobject]
    3.     <SpriteRenderer>
    4.       + [Gameobject]
    5.         <SpriteMask>    //Same sprite as above
    6.           + [Gameobject]
    7.             <SpriteRenderer>    //Masked sprite
    Since I can show the masking sprite I might be able to adjust this structure to see if it works. But in reality the parenting and childing may be lot more complicated.

    Thanks for the quick response! I'll response again after attempting.
     
  25. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Your hierarchy:

    screen.jpg

    It is very important to set proper sorting order in that way: SpriteMask.sortingOrder < SpriteRenderer.sortingOrder.
     
  26. iolloi

    iolloi

    Joined:
    Aug 11, 2016
    Posts:
    3
    Hi Pol231,

    I made a few tests here, it seems that the mask works fine, it is just the Gizmo showing wrong. I tried to combine the mask and the masking sprite, then the fact is the Gizmo displays wrong when it is under more than 1 parent layers.

    Please see the example below:
    1.gif 5E0O%5C537LT{_O2`WDOY9J.png

    I've set the main gameobject to scale x = -1 and rotate the second layer gameobject.
    I used the following code to make sure the mask updates all the time:
    Code (CSharp):
    1.     void Update () {
    2.         GetComponent<SpriteMask> ().update();
    3.     }
    And the mask works fine whatever the Gizmo looks like.
     
  27. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    That's strange with the gizmo. I will look into it later.

    Note that updating SpriteMask every frame costs CPU time. Best option is to update SpiteMask only when it's required.
     
  28. sirio21

    sirio21

    Joined:
    Mar 11, 2013
    Posts:
    114
    Hi, it possible to use as mask an alpha texture? (calculating the alpha result pixel)
     
  29. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi,
    Unfortunately alpha masking isn't supported. Via Stencil Buffer one can mask or not (0 or 1).
    Cheers!
     
  30. GastonC

    GastonC

    Joined:
    Aug 26, 2012
    Posts:
    38
    Hello @PoL231 , got a quick question.

    Im creating 2 different "masks" on the same scene. They work perfectly on their own, but when they "overlap", they are conflicting with eachother. I checked, and they use different materials, so I dont know why this is happening.

    Any idea?
     

    Attached Files:

  31. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi GastonC,

    All you need to do is to set proper sorting order on SpriteMask and masked sprites. For example:
    Code (CSharp):
    1. SpriteMask1 (sortingOrer: 10)
    2.     Sprite1.1 (sortingOrder: 11)
    3.     Sprite1.2 (sortingOrder: 12)
    4. SpriteMask2 (sortingOrder: 20)
    5.     Sprite2.1 (sortingOrder: 21)
    6.     Sprite2.2 (sortingOrder: 22)
    Cheers!
     
  32. GastonC

    GastonC

    Joined:
    Aug 26, 2012
    Posts:
    38
    Worked like a charm! Thxs a lot!

    Another quick question, now that this is resolved. There is no way to do this with only 1 material, to earn in performance? (there will be 9 masks that are exactly the same in the screen). Or would that cause the issue I was having before?
     
  33. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Actually it is possible to optimize masks on your scenario. You can use 'masking parts'. See scene '07 - Masking Part' from Examples folder. You can use 1 SpriteMask, that use 9 SpriteRenderers (with extra SpriteMaskingPart component) to construct a mask. All SpriteRenderers will be batched in to 1 draw call.

    Like in this demo. This scene "costs" only 4 draw calls:
    * 1 for all trees and animals (they create the mask + 'Show Mask Graphics')
    * 1 for all blood sprites (regular SpriteRenderer)
    * 1 for background sprite
    * 1 for OnGUI
     
  34. JSwanFin

    JSwanFin

    Joined:
    Apr 10, 2013
    Posts:
    19
    I bought Sprite Mask. I our bit unusual case I would like to use texture mask in pixel perfect size based on the texture. However, there is no ready made option for that. I could and probably will write it myself, but just checking whether that is planned?
     
  35. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi JKyy,

    Currently there are no plans to write that feature.

    Cheers!
     
  36. JSwanFin

    JSwanFin

    Joined:
    Apr 10, 2013
    Posts:
    19
    Nevermind, I was overcomplicating stuff. Type Sprite seems to do exactly what I want :)
     
  37. thunderdev321

    thunderdev321

    Joined:
    May 5, 2016
    Posts:
    5
    Hi, I need an inverted mask on a canvas raw image. I've got a webcam texture on the raw image, and would like to make a cut out for taking a snapshot. Was wondering if that's possible ?

     
  38. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi thunderdev321,

    SpriteMask doesn't work on UI components, so it won't work on UI Image, but it works on SpriteRenderers. And yes... SpriteMask has an Inverted masking feature. How it works, you can check here.

    Cheers!
     
  39. markzorn

    markzorn

    Joined:
    Oct 6, 2016
    Posts:
    12
    Am I able to dynamically change the vertices of the custom mesh to change the mask at runtime?

    If so, do you have an example of this?
     
  40. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi markzorn,

    Yes, you can change your custom msh at runtime. Just set type to CustomMesh, and set your mesh:

    Code (CSharp):
    1. SpriteMask spriteMask = GetComponent<SpriteMask>();
    2. spriteMask.type = SpriteMask.Type.CustomMesh;
    3. MeshFilter meshFilter = spriteMask.GetComponent<MeshFilter>();
    4. meshFilter.sharedMesh = YOUR_MESH;
    If you need more help just let me know.

    Cheers!
     
  41. markzorn

    markzorn

    Joined:
    Oct 6, 2016
    Posts:
    12
    Thanks for the quick response - I will check it out a bit later.
     
  42. yii7

    yii7

    Joined:
    Jan 22, 2014
    Posts:
    2
    Hi I bought your plugin couple of days ago, it seems to work fine for individual objects. But I wasn't able to use same spritemask material on multiple objects.

    I'm using the a sprite mask for portals, each time I duplicate or create a new game object your spritemask script assigns a new "Owner ID" to this new objects material. This makes the character work only with one portal.

    I may need to use hundreds of portals and its not feasible to work with a system like this. Is there a way where objects can use the same sprite mask material ? Or disable "random owner ID" thing altogether ?

    Edit : I also plan to use different kind of portals in the future so I need a solution which works for multiple prefabs / different object masks.
     
  43. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi yii7,

    In your use case you can use one SpriteMask with unlimited number of SpriteMaskingPart's, which act as part of the whole mask. See example scene: '07 - Masking Part'.

    If you need more help, just let me know.

    Cheers!
     
  44. yii7

    yii7

    Joined:
    Jan 22, 2014
    Posts:
    2
    Hi PoL231;

    Thanks for a solution, but I would prefer an easier method for such a task. It would be very good if you would add 2 materials which just mask each other. Example : "Mask Material" and "Masked Material ; where all objects which are assigned these would mask each other regardless of hierarchy. Your system is pretty detailed but its an overkill for what I'm looking for. Since you already have these materials maybe you can make a variant and add to your plugin for users who are looking for a simple way and don't know about shaders.

    Thanks again.
     
  45. Aedous

    Aedous

    Joined:
    Jun 20, 2009
    Posts:
    244
    Just to keep you informed, I just updated to Unity 5.50f3 and your SpriteMask errors on the console.
    It appears to be this line here round about line 858:
    Code (CSharp):
    1. if (ms [i] == null || !hasStencilSupport (ms [i]) || forceDefaultMaterialOnChilds) {
    2.                                 ms [i].renderQueue = spriteRenderQueue;
    3.                                 updateMaterial (ms [i], stencil, comp, null);
    4.                             }
    I had to change it to something like this in order for it work, I just made sure it doesn't pass if it's null:
    Code (CSharp):
    1. if (ms[i] != null)
    2.                             {
    3.                                 if (ms[i] == null || !hasStencilSupport(ms[i]) || forceDefaultMaterialOnChilds)
    4.                                 {
    5.                                     //Debug.Log("MS " + i + " : " + ms[i].renderQueue);
    6.                                     ms[i].renderQueue = spriteRenderQueue;
    7.                                     updateMaterial(ms[i], stencil, comp, null);
    8.                                 }
    9.                             }
    I'm not quite sure why you are checking whether shared material is null, and if it is, setting the render queue. The object wouldn't exist at that point? unless there's something I'm missing please let me know if I've completely broken your code :D

    Thanks! it's a great asset by the way, I'm using it extensively in Eitr.
     
  46. amyhohoilam

    amyhohoilam

    Joined:
    Nov 26, 2015
    Posts:
    1
    Hi there,
    May I know if there's any previous version that would support Unity 5.3?

    And are there any schedule to support spine?

    Thanks!

    Amy
     
  47. startleworks

    startleworks

    Joined:
    Jun 8, 2013
    Posts:
    34
    I need to use this asset with Unity's Anima2D. But Anima uses SpriteMesh, not SpriteRenderer.
    I tried changing the material to use SpriteMask's Default shader but that didn't work.
    Any idea for a workaround?
     
  48. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi saruzaru,

    Anima2D uses Unity build in 'Sprites/Default' shader, which doesn't support Stencil buffer. If you try to change shader then SpriteMeshInstance.OnRenderObject() method will restore the material to the default one from SpriteMesh. I think, you have to set (somehow) proper shader on default material of SpriteMesh.

    I hope this will help you.
    If you need more help just let me know.

    Cheers!
     
  49. Khena_B

    Khena_B

    Joined:
    Aug 21, 2014
    Posts:
    273
    Interested in buying this but i have some questions:

    Does it support gradients, i'm trying to fake lights in a 2D game, here's an example from someone's project. He's masking a black plane giving the illusion of lights.



    Will i be able to use my own shaders, i use shaderforge and shaderlab.

    Thanks.
     
  50. PoL231

    PoL231

    Joined:
    Jun 27, 2014
    Posts:
    148
    Hi KhenaB,

    Gradient masking is not supported due to Stencil buffer limitations. All you can achieve is this: http://truesoft.pl/sprite_mask/example1/

    You can use your own shader, no problem with that. All you need to do is to extends your shader with Stencil buffer support (few lines of code)

    Cheers!