![unity 3d platformer character controller jump unity 3d platformer character controller jump](https://img.itch.zone/aW1hZ2UvNjUxODAyLzM0OTk5MzgucG5n/original/ab9Zni.png)
…which is much simpler and far more concise! By building a velocity variable this way, we’re able to keep track (and modify) our player’s total movement vector at any time. Running the game will show the results of what we’ve done: our controller can now only move when he is grounded on the floor.
![unity 3d platformer character controller jump unity 3d platformer character controller jump](https://i.ytimg.com/vi/-jWSwjCBz-M/maxresdefault.jpg)
Place this just above the final call to Move, and then replace the current controller.Move call with this: controller.Move(velocity * ltaTime)
![unity 3d platformer character controller jump unity 3d platformer character controller jump](https://i.ytimg.com/vi/CCQ-HIyHHZc/hqdefault.jpg)
Let’s put them together using the following line: Vector3 velocity = moveVelocity + yVelocity * Vector3.up You’ll notice now that at any given frame, we are able to access our controller’s total velocity. Our keyboard movement is stored in moveVelocity, and our up-down in yVelocity. We’re not doing much new here-it’s simply a few lines of code we’ve written before compiled together into one, and then the result stored in moveVelocity. Remove the line that retrieves the keyboard input, and in the if statement that checks if the controller is grounded place this line: moveVelocity = transform.TransformDirection(new Vector3(Input.GetAxisRaw('Horizontal'), 0, Input.GetAxisRaw('Vertical'))) * speed Next, let’s make sure that we can only move our character when our feet are on the ground. This will store our characters velocity on the Z-X plane, controlled by WASD. Since this means that we’ll need to keep track of our character’s velocity at all times, let’s add a new variable to do so: private Vector3 moveVelocity = Vector3.zero Our next step is to remove the ability to move in-air, as well as ensure our controller maintains his forward velocity after jumping. In addition to being more efficient with computational resources, it also makes the code much cleaner and easier to read. For example, we would change the line checking the isGrounded property to the following if (controller.isGrounded) To make use of the variable, replace all the GetComponent calls with “controller”.
Add this line inside it: controller = GetComponentWe’ll do this in the Start() method, which is called exactly once on every script. It won’t retrieve the component automatically we’ll have to call GetComponent once to get the object. This will store a reference to the CharacterController attached to our Player object. Add the following variable to the class: private CharacterController controller Instead, we’ll cache the component in a variable. While this works fine, it’s a waste of resources to call this method over and over each frame, when the returned value never changes. You’ll notice each time we want to make use of the CharacterController, we need to call the GetComponent method. Before we sink our teeth into this delicious new feature, we should begin to do some cleanup in our code. Sadly, we’ll never pirouette as gracefully as he does.