Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Weird Issue With Sprite Masks Overlapping

Discussion in '2D' started by jlars789, Sep 12, 2023.

  1. jlars789

    jlars789

    Joined:
    Mar 3, 2023
    Posts:
    16
    Hello,

    I have a pretty good implementation of textures on entities that are affected by a status effect. I have a base sprite (8x8) that is scaled up using the Repeat scaling, with Tiled Slicing on the Sprite Renderer. This means that that 8x8 pattern is repeated for whatever scale it is used on. I then scale the tiling up to match the rectangular size of the entity. After that (because my entities are not rectangles), I set the Status Effect's Sprite Mask's Sprite to be the Sprite of the entity it is affecting. I also set the Status Effect's transform's parent to be the transform of the entity being affected.

    This works really well - with two exceptions. 1) When multiple entities of the same type (i.e., they share the same Sprite) are close and they both share the same Status Effect, the status effect from the other entity will "bleed through" over to the other entity. While this may not seem like an issue, as they have the same effect, I allow the stacking of Status Effects, and they have a low individual alpha, as to increase the visual impact as more stacks are accrued. This means a clear rectangle can be seen where the two effects intersect. My assumption here is that the two Status Effect's Sprite Mask's point to the same Sprite, meaning that they effectively have the same Sprite Mask, so when a new Sprite Mask enters its rectangle, it is shown there too.

    The smaller issue being that the effect will overlay on anything between their two layers. Because the Status Effect and Entity are separate GameObjects, they must have some form of layer sorting. My current method is placing it one Sorting Layer above the entity that's being affected, but when multiple entities of the same type are close (and intersecting), the Status Effects will overlay. This is less of a concern than the previous issue.


    My current idea is to Create a new Sprite using the same data as the Entity's Sprite, but I fear this will devour memory for no reason besides creating a new pointer - as the only reason I am creating the sprite is to tell Unity's masking system "these are not using the same mask". To clarify, I just want the same *shaped* mask, but not the same mask.

    I was wondering if somebody could give me some clarification as to how SpriteMasks work in the background so I can understand a bit more about what's going on here.
     
    Last edited: Sep 12, 2023
  2. jlars789

    jlars789

    Joined:
    Mar 3, 2023
    Posts:
    16
    As an update: I tried creating a new Sprite by Instantiating the Entity's sprite, but the crossing effect still happens.

    As a further update: It seems as if this is a Unity-end issue. Sprite Masks seems to be a global entity (even if they are attached directly to a component) and all Sprite Masks affect all Sprite Renderers that are allowed to interact with masks. I'll refrain from giving my opinion on how utterly stupid it is that this is not a setting you can configure, but I believe I have a workaround by using Sorting Layers. I will assign each entity a random sorting value based on their size, then assign the Status Effect and its mask to have the same Sorting Value+1. The mask will have a range of 1, so unless these randomly assigned values are identical, then they should not intersect. This should minimize overhead of assigning values in a "smart" way.
     
    Last edited: Sep 12, 2023
  3. jlars789

    jlars789

    Joined:
    Mar 3, 2023
    Posts:
    16
    Replying to myself (again), I found how this works - you use Sorting Groups: https://docs.unity3d.com/ScriptReference/Rendering.SortingGroup.html. I am leaving up my frustrated reply before this. I do stand by the fact that it would be utterly stupid if there wasn't a way to configure which SpriteMasks work with which SpriteRenderers. Luckily, there is one!