Hello everyone!
I tried posting this in UnityAnswers, but Answers seems to be completely broken at the moment, so I hope you guys can help me.
This is my problem:
I’m building a 2D platformer using rigid bodies and Unity physics. Everything seems to be working as intended, except my player frequently gets stuck on the corners of solids. When this happens, you can zoom in real close on the player and the solid, and you can see that the box collider for the player is inside the box collider for the solid by the teeniest tiniest fraction of a unit. When you get stuck, you can’t move at all, which really puts a damper on the whole 2D platforming experience.
Here’s my script: (Javascript)
//************************ 2D Platformer Player Script ************************ //
//Author: Aaron Hoffman (Zanzindorf)
//Date: January 2, 2013
// NOTE: Attach this script to default shape like a cube.
//Control keys
var jumpKey: KeyCode;
var leftKey: KeyCode;
var rightKey: KeyCode;
//Raycast information
var hit: RaycastHit;
//Jumping
private var maxJumpPower: float = 150; //Max charged power of a jump
public var jumpPower: float = 0; //Current power of jump
private var jumpChargeRate: int = 40; //Rate at which player charges a jump
//Movement
private var moveForce: float = 0; //Force applied to player object when walking (Acceleration)
private var maxMoveSpeed: float = 20; //Max speed of the layer
private var groundSpeed: float = 60;
private var airSpeed: float = 3;
//Initialize values and physics components
function Start () {
gameObject.AddComponent(Rigidbody);
rigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotation;
Physics.minPenetrationForPenalty = 0.00001;
Physics.bounceThreshold = 0;
jumpKey = KeyCode.Space;
leftKey = KeyCode.LeftArrow;
rightKey = KeyCode.RightArrow;
}
function FixedUpdate() {
/////////////// Jumping ///////////////
if (Physics.Raycast(transform.position, Vector3(0,-1,0), hit, transform.localScale.y)) //Make sure player is standing on ground
{
if (Input.GetKey(jumpKey) rigidbody.velocity.y >= 0) //Charge jump if key is pressed and limit is not reached
{
rigidbody.AddForce(Vector3(0,maxJumpPower,0));
}
moveForce = groundSpeed;
}
else
{
moveForce = airSpeed;
if (!Input.GetKey(jumpKey) rigidbody.velocity.y > 0)
{
rigidbody.AddForce(Vector3(0, -50,0));
}
}
/////////////// Movement ///////////////
if (rigidbody.velocity.x < maxMoveSpeed Input.GetKey(rightKey) !Physics.Raycast(transform.position, Vector3(1,0,0), hit, 1))
{
rigidbody.AddForce(Vector3(moveForce,0,0));
}
if (rigidbody.velocity.x > -maxMoveSpeed Input.GetKey(leftKey) !Physics.Raycast(transform.position, Vector3(-1,0,0), hit, 1))
{
rigidbody.AddForce(Vector3(-moveForce,0,0));
}
}
I’m using Addforce for my main mode of moving the player. I’ve tried adding a function that detects if the player is inside a solid using the OnCollisionStay function, but that function seems to trigger even if the player collider is touching another collider. I need it to trigger only when the player collider is inside another collider.
I can’t figure out a way to do this. I’ve tried making a second collider on the player that’s a fraction smaller than its default box collider, but again, the small distance that the player is getting stuck inside other colliders is so small, it’s impossible to shrink the secondary collider down precisely enough to rule out all probability of getting stuck.
Screen Capture of player collider (top box) getting stuck inside a solid (bottom block):
In the image, the player is stuck relitively far into the solid. Most of the time, the distance into the solid is a lot less, but it’s hard to recreate.
What I’ve already tried:
- Adjusting the bounceThreshold - No effect regardless of what value I tried.
- Adjusting the penitrationThreshhold -Much of the same.
- Rigging up a slightly smaller collider which pushes the player out when triggered - Couldn’t re-size second collider precisely enough to rule out any chance of getting stuck.
- Screaming really loud - No help, but it felt good.
If you have ideas, help would be muchly loved.
Thanks, and have a nice day,
Zanzindorf