- Home /
Best practice for avoiding bad collisions when rotating a Rigidbody2D player?
I'm building a 2D Platform game where my player spins 360 degrees when they jump. I've implemented the 360 spin several different ways, all of which result in different tradeoffs and bugs. I want to get some advice about the best way to deal with this long term for a non-trivial game.
Description of my game:
- A player has a RigidBody2D with three colliders:
Head = CircleCollider2D
Torso = BoxCollider2D
Feet = CircleCollider2D
The walls, floor, and ceiling are EdgeCollider2Ds.
I've set Collision Detection to Continuous on my player's RigidBody2D and that has helped a lot.
Ways To Spin 360 degrees:
Spin the player directly ignoring RigidBody physics:
float degreesToSpin = Mathf.Lerp(0f, 360f, spinRatio); player.transform.eulerAngles = new Vector3 (0f, 0f, degreesToSpin);
The problem with this approach is that manual rotating will rotate right past a collision that a rigidbody might normal handle and the EdgeCollider2D on the ceiling can get stuck between the head and torso OR the player can end up on the other side ceiling's EdgeCollider2D.
Workarounds:When spinning put a circle collider around the entire player. Downside: This creates a forcefield that creates collisions that might not normally happen and pushes the player away from walls.
Each frame RayCast from my previous position to see if I have gone through anything. Downside: results in buggy looking player jumping backwards. Theoretically could create an infinite loop.
Haven't tried yet: Rotate, RigidBody.Cast(), if there is a collision rollback the rotation.
Let RigidBody2D do the rotation:
float degreesToSpin = Mathf.Lerp(0f, 360f, spinRatio); player.rb2d.MoveRotation(degreesToSpin);
This approach reduces the amount of times I get stuck on or on the other side of EdgeColliders, but that still happens once in a while.
Downside:
About 20% of the time, I get huge ricochets when a platform blocks a rotation. I want the player to spin against anything it hits, not bounce off with a large velocity. I'm guessing I can mitigate this by changing the material.bounciness coefficient or setting the velocity to a low number during OnCollision.
The rotation results in some of my upward velocity getting transferred to horizontal velocity which is realistic, but I do not want it.
What is the best way to implement platformer style player spinning, on a non-trivial game?
I have much less problems with BoxCollider2Ds or anything with width. My gut tells me I should reimplement all of my world's walls as BoxCollider2Ds or PolygonCollider2Ds. This will probably save me a lot of future headaches with other types of objects going through the EdgeCollider. Is this assertion correct?
The best way would be to calculate the torque needed and alter that on the rigidbody. That would be Physics-Engine-ally 100% accurate