- Home /
Controlling direction while jumping using CharacterController
Hi, I know this question has been asked (and solved) before, but I have had no luck with using previous solutions.
I'm fairly new to scripting in Unity, but I was doing okay until now… I just don't understand this one thing.
I have a simple CharacterController move script and can move, turn, jump, etc. Only problem is, once I jump in a direction, I'm locked there. I have it set up to allow turning in mid-air, but I still cannot move on the Z axis.
I know about the apparent fix, removing "IsGrounded" but that has not worked for me. Can anyone help me?
Thanks. :)
My script:
var speed : float = 6.0;
var jumpSpeed : float = 8.0;
var turnSpeed : float = 60;
var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
var controller : CharacterController = GetComponent(CharacterController);
var turn: float = Input.GetAxis("Horizontal");
transform.Rotate(0, turn * turnSpeed * Time.deltaTime, 0);
if (controller.isGrounded) { // only move or jump if grounded
moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
controller.Move(moveDirection * Time.deltaTime);
}
Answer by aldonaletto · Dec 17, 2011 at 11:57 PM
You must move the moveDirection calculation outside the isGrounded if - but this screws up the gravity effect, because moveDirection.y is zeroed each Update. To avoid this problem, store the vertical speed in a separate member variable, and assign it to moveDirection.y prior to move the character. Extra feature: you can store the CharacterController in another member variable (variable declared outside any function) only once, what will speed things a little. The whole thing is:
var speed : float = 6.0; var jumpSpeed : float = 8.0; var turnSpeed : float = 60; var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero; private var vSpeed : float = 0; // keep vertical speed in a separate variable private var controller: CharacterController; // controller reference
function Update() { if (!controller) controller = GetComponent(CharacterController); var turn: float = Input.GetAxis("Horizontal"); transform.Rotate(0, turn turnSpeed Time.deltaTime, 0); moveDirection = transform.forward Input.GetAxis("Vertical") speed; if (controller.isGrounded) { vSpeed = 0; // a grounded character has zero vert speed unless... if (Input.GetButton ("Jump")) { // unless Jump is pressed! vSpeed = jumpSpeed; } } // Apply gravity vSpeed -= gravity Time.deltaTime; moveDirection.y = vSpeed; // include vertical speed // Move the controller controller.Move(moveDirection Time.deltaTime); }
Ah, that worked. I understand the problem/solution and didn't just copy your code for no reason. Just so you know your intelligent reply wasn't wasted.
Thank you so much. :)
Congratulations, that's the spirit: understand the idea and implement it yourself!
By the way, please click the "check" button below the voting thumbs to mark this answer as accepted - this will help others to find the solution for similar problems.
I was fighting also with this gravity problem for few days. With little tweaking I got it working and now I can make mid air jumps in my 2d jumper. I couldnt do it without this sample! Thank you :)
Dude, Thank you so much! You saved me! I was trying to figure this out for weeks!
thank you so much for this. It's amazing that not knowing a concept can eat hours out of your work.
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Player movement 0 Answers
A better way to do jumping? 2 Answers
Lerp & jumping with sin/cos 1 Answer