While developing Langman (an early prototype of Plangman), much of my time was spent tweaking the PlatformerController script from the 2D Lerpz tutorial. I made some changes to how it works, and along the way I encountered (and fixed) a number of bugs in the original script. I’m sharing my changes in the hope that others will find them useful.
You can download the sample project here. As usual, feel free to use this code in your own projects.
- In-air movement is calculated more like running movement. When you release the arrow keys, horizontal movement gradually slows to a stop. The old logic was suitable for a jetpack, but not a traditional platformer.
- EDIT: The jumping logic now allows jumps slightly after the character leaves a ledge.
- EDIT: The script now uses Time.smoothDeltaTime instead of Time.deltaTime.
- I’ve stripped out a bunch of things I didn’t use, such as having different walk vs. run speeds, the particle effect stuff, etc.
- Respawning from a moving platform sometimes caused the player to be affected by the platform’s position in the respawn frame. To remedy this, activePlatform is set to null in Spawn.
- When standing on a platform, the character could be pushed through walls and other obstacles. To remedy this, the effect of a platform’s movement on the character is not directly applied to the transform. Instead, it is combined with the other movement input and passed into CharacterController.Move, which handles collision detection.
- EDIT: It turns out that for moving platforms, transform.position must be updated directly. If this isn’t done, the character will eventually fall through the platform. The code now modifies transform.position directly when the character is standing on a kinematic rigidbody that has a non-zero velocity.
- If the character brushed a block diagonally when jumping, he could end up floating slowly upward. This unintentional flying ability was remedied by detecting ceiling collision as part of determining whether the apex of the jump has been reached.
- In certain cases, when jumping while standing on a falling block, the character could end up jumping/landing without ever leaving the block, making it seem like the jump key wasn’t responding. This was fixed by getting rid of inAirVelocity and not making the jump velocity dependent on the velocity of the active platform.
I also modified PlatformerPushBodies. The primary changes I made were to comment out the layer stuff since I wasn’t using it and to only change the velocity of the rigidbody being pushed if the rigidbody’s velocity was less than the character’s. Without the latter change, rollable spheres would “stick” to the character when the character stopped moving.
The project also includes a double-sided vertex-lit shader, which is used for rendering both sides of the character sprite.