Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Pixel Perfect Collision Mapping/Masking - Does It Exist?

Discussion in '2D' started by KevinConner, Jan 8, 2022.

  1. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11
    I was convinced into learning Unity because Unity is pushing this narrative that it now fully supports 2d game programming.

    I'm frustrated though.

    After spending a great deal of time learning Unity 2d programming, I instead have discovered that NONE of Unity's collision masks are Pixel Perfect.

    I can deal with the inability to swap sprites in a pre-baked Animation Sequence. That's ok, I don't need that functionality often.

    But I absolutely need a Pixel Perfect Collision Mask.

    IS there a Pixel Perfect Collision Mask in Unity!?

    Is there a way to HARD CODE a Pixel Perfect Collision Mask in unity?

    Do I have to abandon Unity's Animation system to create individual polygonal pixel masks around EACH AND EVERY sprite in my game?

    Or is there a way to create a Bitmap Image that is a Collision Mask to operate for each frame of animation?

    I've seen some posts dating back to 2011 on this issue and one person answered with a script that is NO LONGER supporter by Unity.
     
    Last edited: Jan 8, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    If you're using physics to bump things together, they won't be pixel-perfect.

    Not only that but for something to bump, it actually has to penetrate and overlap by some minimal amount, otherwise it just isn't mathematically colliding.

    If you are just looking to query if something is a pixel or not, you could use the Texture2D.GetPixel() calls to decide.

    You could also preprocess your textures into colliders and use the Physics2D overlap stuff.

    I demo the process of reading a Texture2D pixel by pixel and creating a related set of quads in the scene along with BoxCollider2Ds on them in my MakeGeo project. Look for the
    TestTexture2BoxCollider2D
    scene specifically and read the use notes in the source code.

    MakeGeo is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/makegeo

    https://github.com/kurtdekker/makegeo

    https://gitlab.com/kurtdekker/makegeo

    https://sourceforge.net/p/makegeo
     
  3. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    Please explain further as to why you need collision to be pixel perfect. Box2D is unable to achieve this nor would 99% of all the other 2D physics engines out there, unless its designed for pixel perfect collision(I did this in XNA years ago and performance became an issue quickly.)

    One thing you can try is setting the Default Contact Offset in the Physics2D settings, but it isn't recommended. Wish I could find the post where @MelvMay told me or someone else that it wasn't recommended. You could also make PPU lower to make a pixel larger than the Default Contact Offset. Each solution has its trade off though.
     
  4. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11
    I will try to understand this, I'm a bit of a dunce when it comes to technical terminology, however, you did say that this:
    "You could also preprocess your textures into colliders and use the Physics2D overlap stuff."

    I think this is what I'm looking for.

    Yes I do know there will always be overlap, the point is to have a retro game where there isn't a player swiping empty air and hitting an enemy, or an enemy swiping empty air and damaging the player. That the actual contact has to have overlap over JUST the area covered by the sprite.

    The collision map is essentially the sprite area itself. Engines like GameMaker do this already. I think they ignore any overlap where there is a transparent tile. I found no way to do this in unity. I will try to look at this though..

    if anyone else has any ideas or can help explain the code to me please respond.
     
  5. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11
    Because I don't like making games where a character can punch air and damage another character. I don't care if the pixels overlap, I just don't want enemies and characters to be swiping air and dealing damage.

    I'm not sure this would achieve the desired effect.

    I'm talking about having a basic sprite mask, where when the sprite mask is overlapped by another sprite, then a collision is detected.

    In fact, is it possible to turn a sprite mask into a collider? or for that matter, is it possible to force Unity to automatically make the polygoncollider2d exactly match a sprite?
     
    Last edited: Jan 9, 2022
  6. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    This can be achieved in other ways. For melee attacks I've always used triggers or direct queries. I try to make it overlap so there is no "air" in between. Pixel perfect or not, you are not going to have the accuracy you want without tweaking things to work and even then it might not be exactly how you want it. Game development isn't easy, everything needs to be tweaked to get it the way, or close enough to the way you want it.
     
  7. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11
    ok well that doesn't help resolve my question. As I said before I've made games but in other engines. So I know what game development is like. I'm specifically trying to find a low resource solution.

    Is there a way to detect if a sprite mask passes over a sprite? That would resolve all of my questions. Otherwise someone suggested to me that I manually animate each frame and have a polygon 2d collider manually placed over the sprite.
     
  8. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    I do not use the physics engine for a 2D pixel game.

    You have to use rectangles for detection because you have limited processing power but you can make it appear like pixel perfect collisions to the player.

    In this example below we compare two rectangles with a LeftTop pivot. If true then they overlap.

    Code (CSharp):
    1.             if (Rect1.left - Rect1.width < Rect2.left + Rect2.width &&
    2.                 Rect1.left + Rect1.width > Rect2.left - Rect2.width &&
    3.                 Rect1.top + Rect1.height > Rect2.top - Rect2.height &&
    4.                 Rect1.top - Rect1.height < Rect2.top + Rect2.height)
    5.             {
    6.                 return true;
    7.             }
     
    Last edited: Jan 9, 2022
  9. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,131
  10. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11
    Interesting interesting...
     
  11. KevinConner

    KevinConner

    Joined:
    Jan 8, 2022
    Posts:
    11