Hello, it looks like Physics2D.OverlapCapsule() is detecting triggers as if they were about three times as tall as their original colliders height.
I’m using OverlapCapsule exactly following the parameters of a capsule I have attached in my player. When a collider is detected within, the player is moved out of it, but if such collider is a trigger a new scene is loaded.
The behavior with non-triggers is correct. The player is stopped from getting into the colliders.
The behavior with triggers, however, is unexpected. It behaves as if they were taller than they really are.
Please see here for the relevant code part:
//This code vvvvvvvvvvvvvvvvvvvvvvvv is from this tutorial:
//https://roystan.net/articles/character-controller-2d.html
//with a few changes and I will be syncing the transforms manually instead
Physics2D.OverlapCapsule(coll.bounds.center, coll.size, coll.direction, 0, contactFilter2D, collidedColliders);
foreach (Collider2D hit in collidedColliders) {
if (hit==null)
continue;
if (hit == coll)
continue;
if (hit.isTrigger) { //Treat a trigger like a trigger ¬L¬
//NOTE: For some reason, as soon as the trigger checkbox is ticked
//trigger colliders appear to become bigger in height when detected by OverlapCapsule
//than they really are. The collider gizmo is still drawn as the original size tho.
//It appears to be about three times as high.
Destination d=hit.GetComponent<Destination>();
if (d) { //A teleport!
if (d.ignorePosition) {
GameManager.instance.startInSetPosition=false;
}
else {
GameManager.instance.startInSetPosition=true;
GameManager.instance.startingPosition=d.position;
GameManager.instance.startingFacing=d.facing;
}
SceneManager.LoadScene(d.sceneName);
}
}
else { //Move out of the collider
//debugPoints.Add(new DebugPoint(hit.bounds.center, Color.red));
ColliderDistance2D colliderDistance = hit.Distance(coll);
if (colliderDistance.isOverlapped)
transform.Translate((colliderDistance.pointA - colliderDistance.pointB));
}
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you can spare some time and bandwidth feel free to checkout my project here:
If you do so, try to walk around the square collider on the right side and check how the player capsule bounds don’t get into its bounds, then tick the colliders “isTrigger” setting, and check how you cannot walk as closely to it around the top and bottom sides as the trigger will activate.
Is this a bug or am I doing something wrong?
I’d urge you to help now if you can as I’m in the middle of an interview. Thanks!
Maybe you should use the result count returned from that call and only look at that many results. Checking for null isn’t a valid method of iterating the results, it should be from 0 to resultCount-1. Also note you can pass a “List” instead of an array so you never miss results.
Note you can go into the “Physics 2D Project Settings > Gizmos” and there’s a bunch of options there for showing colliders and also for showing the collider bounds (AABB). You’ll see they don’t change when you change trigger state; it’s not related at all.
TBH just looking at your player stuff indicates some really bad practices. Such as you modifying the Transform which is the number one rule you shouldn’t do with physics. That’s what a Rigidbody2D is for; use its API. This is why you’re having to perform an expensive sync-transforms to sync-up any colliders here maybe. Reading input during FixedUpdate etc.
I was honestly hoping modifying the code as per your suggestions would actually fix the problem. Because of what you said, I thought maybe I was checking some ghost colliders or random data in the non-overwritten parts of the array. But somehow it’s still detecting the triggers as if they were taller. All colliders are being shown in the project and indeed the colliders get to keep their original size, only that it would seem as if they were taller to OverlapCapsule(). I have no clue what may be off here… Any more ideas?
As for the other remarks, true. I still have a long way to go in regards to proper practices. I’m not sure if I made the Update into a FixedUpdate because I was unsure if I could run SyncTransforms() in update, and then I forgot to take out the input checking into Update. I’m not really using physics for anything else than checking colliders through OverlapCapsule, so I thought I would be fine to modify the transform directly in this case.
//This code vvvvvvvvvvvvvvvvvvvvvvvv is from this tutorial:
//https://roystan.net/articles/character-controller-2d.html
//with a few changes and I will be syncing the transforms manually instead
int hits=Physics2D.OverlapCapsule(coll.bounds.center, coll.size, coll.direction, 0, contactFilter2D, collidedColliders);
for (int i=0; i<hits; i++) {
if (collidedColliders[i] == coll)
continue;
if (collidedColliders[i].isTrigger) { //Treat a trigger like a trigger ¬L¬
//NOTE: For some reason, as soon as the trigger checkbox is ticked
//trigger colliders appear to become bigger in height when detected by OverlapCapsule
//than they really are. The collider gizmo is still drawn as the original size tho.
//It appears to be about three times as high.
Destination d=collidedColliders[i].GetComponent<Destination>();
if (d) { //A teleport!
if (d.ignorePosition) {
GameManager.instance.startInSetPosition=false;
}
else {
GameManager.instance.startInSetPosition=true;
GameManager.instance.startingPosition=d.position;
GameManager.instance.startingFacing=d.facing;
}
SceneManager.LoadScene(d.sceneName);
}
}
else { //Move out of the collider
//debugPoints.Add(new DebugPoint(hit.bounds.center, Color.red));
ColliderDistance2D colliderDistance = collidedColliders[i].Distance(coll);
if (colliderDistance.isOverlapped)
transform.Translate((colliderDistance.pointA - colliderDistance.pointB));
}
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}