Let me start off by saying that I’m pretty new to programming/game development/Unity3d. I’m working on a 2d platformer in Unity and I ended up taking a lot of code from the 2D Gameplay Tutorial.
I ran into a bug with the platformer controller where if you clipped the edge of a platform from below, and continued holding the jump button, the character would begin floating until it hit it’s extra jump height. If you don’t know what I’m talking about, there’s a video at the end of the post.
Is anyone else basing your game off the 2d tutorial? Have you noticed this?
What’s causing this? If I’m reading the code correctly, when the character jumps, gravity isn’t being applied until the extraPowerJump == false. In order for extraPowerJump to be false the any of following conditions need to be met - either jump.jumping is false, the character has reached his apex (movement.verticalSpeed > 0.0), the jump button isn’t pressed, the character has reached his target height, or the character hits the ceiling (IsTouchingCeiling).
It looks like when you clip the corner of a platform, IsTouchingCeiling doesn’t register it as a ceiling hit so the jump continues, also the character picks up the deceleration from the collision.
I think I found a fix. We just have to apply gravity at all times, even when we’re jumping. In the ApplyGravity method of the PlatformController script I replaced the return; under if (extraPowerJump) with the underlined code:
function ApplyGravity () {
// Apply gravity
var jumpButton = Input.GetButton ("Jump");
if (!canControl)
jumpButton = false;
// When we reach the apex of the jump we send out a message
if (jump.jumping !jump.reachedApex movement.verticalSpeed <= 0.0) {
jump.reachedApex = true;
SendMessage ("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
}
// * When jumping up we don't apply gravity for some time when the user is holding the jump button
// This gives more control over jump height by pressing the button longer
var extraPowerJump = jump.jumping movement.verticalSpeed > 0.0 jumpButton transform.position.y < jump.lastStartHeight + jump.extraHeight !IsTouchingCeiling ();
[B]__movement.verticalSpeed -= movement.gravity/2 * Time.deltaTime;__[/B]
if (extraPowerJump)
[B]__movement.verticalSpeed -= movement.gravity/2 * Time.deltaTime;__[/B]
else if (controller.isGrounded)
movement.verticalSpeed = -movement.gravity * Time.deltaTime;
else
movement.verticalSpeed -= movement.gravity * Time.deltaTime;
// Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.
movement.verticalSpeed = Mathf.Max (movement.verticalSpeed, -movement.maxFallSpeed);
}
I know these are only example files and not guaranteed to be bug free but I know other people are using this code and I want them to be aware.
If anyone has any better suggestions for this, let me know.
video: