Unity Resource: LangmanController

Unity LogoWhile 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.

Primary changes:

  • 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.

Bug fixes:

  • 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.


30 thoughts on “Unity Resource: LangmanController

  1. Fantastic…simply fantastic. We need more guys like you. Numerous people like me who are hopeless at any 3d modelling softwares can benefit greatly from this…thanks a tonne.

  2. Hey Great work on fixing some of the bugs in the platform controller πŸ™‚
    it work heaps better for me now

    i was wondering tho (im newish to unity) how would i go about accessing the ‘gravity’ var from another script on another object


  3. also i cant get your spawn point to work ?
    i draged my object into the inspector and on to spawn point var but it doesn’t spawn there when i run the game

    1. For the spawn point, try calling Spawn().

      To access the gravity from another script, you’d first need a reference to your character game object. Then you could do something like:

      #pragma strict
      var character : GameObject; // Assign this via the inspector
      var controller : LangmanController;
      function Start(){
      // Get a reference to the controller script
      controller = character.GetComponent(LangmanController) as LangmanController;
      // Print the gravity value

  4. does “As usual, feel free to use this code in your own projects.”
    mean I can use this for commercial

  5. Excellent work, your changes have greatly improved the script, but I’m having much difficulty to add buttons in touch (Gui texture). I’m not able to replace the variables (var h = Input.GetAxisRaw (“Horizontal”), and (var jumpButton Input.GetButton = (“Jump”). Help me to spread your script for developers of mobile devices.

    1. For the horizontal axis, you need to translate the pressing of the GUI buttons into a numeric value between -1 and 1. A simple way to do this would be to set h to -1 if the left button is pressed, and to 1 if the right button is pressed (otherwise set it to zero). Same thing with jump, except that it will either be 0 or 1.

      It would be even easier if you could use the Input menu to bind certain touch buttons to certain input axes (such as “Horizontal” and “Jump”), but I’m not sure if that’s possible.

  6. Thanks so much for this script! There is one thing I would like to add, but can’t figure it out. I like to have a bit of a pause before jumping (like a quick crouch to generate the necessary power), I would very much appreciate any help!

    1. You’ll have to store the fact that the jump key was pressed but delay acting on it for a few frames, until the amount of time you’re wanting the character to pause has passed. Hope that helps!

      1. This is what I did:
        – added a variable “preparingJump” and set it to false
        – In the ApplyJumping function, I edited the if-statement under the // Jump comment line, the * marks what I added. It SEEMS to work well, but I wouldn’t doubt there’s a better way to pull it off.

        if (jump.enabled && Time.time 0.0)
        apRbY *= 1.4;
        movement.verticalSpeed += apRbY;

  7. Just started my own 2d game…very new to unity and have been watching tutorials online for 3d. Your scripts are exactly what I wanted!

    Thanks so much for this. I’m not making anything for public release, so this will give me the motivation from giving up due to the complexities/time to make such a smooth flowing controller script.

  8. I’ve been studying the code for a while now but can’t seem to figure out a way to make (a fairly simple way of) changing directions smoother. Keeping your velocity while turning makes landing on platforms fairly difficult. It’s my gamer instinct to press to the opposite direction to slow down mid-jump, but now I’m just launched to the opposite direction, most likely resulting in me falling off or twitching back and forth five to six times before landing. Any help would be greatly appreciated, even just a push in the right direction.

    1. It sounds like you will need two settings: the turn speed when grounded (controller.isGrounded == true), and the turn speed when in the air (controller.isGrounded == false). Hope that helps!

  9. Hello there. I have been trying to fix a weird bug when using PlatformerController which is the ability to “float”. If you repeatedly press jump while running in a certain way, then the character starts floating for a period of time! (e.g. try pressing jump 3 times in a row then hold the jump button while running, this would cause the character to float :D).

    I tried checking for hangTime before changing the speed of movement/running or jumping but it doesn’t seem to do anything!

    Any help would be really appreciated, cheers πŸ™‚

    1. You have to ignore the jump button being pressed if the player releases it while in the air. This is what I did in LangmanController, so look at the sample code linked above if you’d like to see how it works. Hope that helps!

      1. Hey, thanks for the reply. But can you be more specific? The class is complicated for me and I can’t find a comment in your code that talks about ignoring the jump button while in air .. ? May be tell me which line of code you are referring to? cheers.

  10. So by you saying free for use in projects and commenting that you were fine with commercial use do you need/want to be in some form of credits? And may i take out some of you comments such as your name and wjere you got the tutorial?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s