What I think is that that hole in the geometry makes the collision ground normals start to react wierd.
(continue reading to know more about what I mean by weird)
And here its where it gets weird, this only happens if:
The scene where the rooms are is the initial one
The Rooms are deactivated in the first few frames (gameObject deactivated)
The initial room doesn’t have any weird shape like this one (yep it seems that changing one room affects the collision ground normals of others rooms, keep in mind that they do not share anything)
I know this is weird and hard to tell what is going wrong but anyone has any idea about what is happening?
If I have time this weekend I’ll add an example project of this
Contacts are directionless. That’s just the raw normal. It’ll be different depending on what Collider2D you are asking about. If you get the contacts for a specific Collider2D, the normals will be returned in its space. If you look at contacts on a OnCollisionEnter2D for instance, the normals will be for that object. The global gizmos you’re showing here can’t show both otherwise it’d just be two arrows so it shows the raw ones.
The raw contact displayed doesn’t have a specific contact. That purely relates to how the intersection routines works i.e PolygonAndCircle might always be in the Polygon frame of reference.
Beyond that, the images don’t help at all. All I see is show green gizmos and a circle selection.
Where and how are you retrieving contacts, using what API. That should always return it to you correctly? Or are you just worrying because the global gizmos are not what you expect?
I was in a bit of a hurry and I did not give enough information. As you say the global gizmos do not show both normals but I thought they where showing the normals of the dynamic rigidbody (player) and not the static one (scenario), anyway its not related the issue I’m having (just added them If they helped).
I’m using Collider2D.GetContacts in each fixed update and on OnCollisionEnter2D and OnCollisionExit2D in the collider (BoxCollider2D) of the player (that has a Rigidbody2D set to dynamic). All this is for checking if the player is touching a wall and/or ceiling and/or ground. And until now this has worked to check the ground giving me a ContactPoint2D (at the bottom of player) that has a surface normal with y=1 (All my grounds are flat).
Right now in the very weird cases that I’m describing both ground ContactPoint2Ds in the player are giving me a y=-1. Usually after jumping against the wall I start to get those values. Another weird thing is that adding some tiles to another tile map with a composite collider in the scene changes the problem in different ways: making it go away, flip the walls that jumping against make the problem show up (edges of the polygon collider facing right or left) or making it easier or harder to get those -1 values.
Just to highlight that you can use Rigidbody2D.IsTouching(ContactFilter2D) to detect “grounded” conditions without the overhead of retrieving and analysing contacts. You can filter by collision normal direction and also do multiple ones if you wish. You can also see this being used here: https://www.youtube.com/watch?v=ZgsrAHGU-mA
Unfortunately there’s nothing I can really say to help you here, no way to debug this. All I will add is that the physics engine knows nothing whatsoever about Unity colliders, it only knows about contacts on the four primitives of Circle, Capsule, Edge and Polygon. A “composite” can produce edges or polygons but those are the same as what the EdgeCollider2D or PolygonCollider2D produce so this won’t be a Unity collider specific thing.
An edge might give you a different normal depending on what side of the edge you are on or if you’re overlapped enough over one side of it. This is the direction that physics will apply an impulse to move your out of overlap.
I thought it would be less performant to do three IsTouching checks but of course I did not test that. Anyway right now I have to check the position of the collision point and retrieve the game object is colliding against for other operations so its I just easier to retrieve them all in one go and have them all available with get contacts.
I’ll put up an example project later in the week so the problem can be easily seen and understood.
One thing I picked up on what you said above; just wanted to make sure you know about the ability to retrieve contacts there without allocating too as opposed to using the “contacts” property which allocates an array. See Collision2D.GetContacts. Also, there are no contacts to retrieve in OnCollisionExit2D, that’s why it’s called.
Finally managed to make an example project, it was a nightmare to find the source of this. I must be missing something really obvious because I don’t see why this is behaving like this.
In this specific case disabling for example the small trigger at the far side right makes the problem go away. But I would like to know why this is happening. Adding a trigger in the scene can interfere with the detection of contacts in some way?
It turns out though that it isn’t the same issue but is fairly similar. I wish I had known about this issue a few weeks back, I would’ve fixed them both at the same time. Unfortunately, for this I cannot think of a good workaround for you but the fix is trivial and has been there for a long time.
So, moving forward, may I ask that you submit a bug report with the above project attached? That way you’ll be able to track the fix and I’ll be able to report back to you here too.
If you can report the incident number then I can push to get that processed by our Customer QA so I can work on it.