FPSWalker script - how to move in midt air?

Hey guys… Do you know how modify the FPSwalker script so that the object it is attached to can move while it’s in the air?

I’m tying to create a script for the Character Controller to control jump(with gravity) movement(left/Right) for a 2D game character.

My character need to be able to move in mid air and I can’t figgure it out at my current level.

Advice much appreciated :slight_smile:

Here’s the FPSwalker script.

var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

function FixedUpdate() {
	if (grounded) {
		// We are grounded, so recalculate movedirection directly from axes
		moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		moveDirection = transform.TransformDirection(moveDirection);
		moveDirection *= speed;
		
		if (Input.GetButton ("Jump")) {
			moveDirection.y = jumpSpeed;
		}
	}

	// Apply gravity
	moveDirection.y -= gravity * Time.deltaTime;
	
	// Move the controller
	var controller : CharacterController = GetComponent(CharacterController);
	var flags = controller.Move(moveDirection * Time.deltaTime);
	grounded = (flags  CollisionFlags.CollidedBelow) != 0;
}

@script RequireComponent(CharacterController)

The if(grounded) conditional is where you want to put your focus. In your situation, you don’t care about whether or not the CharacterController is grounded, so just move that code outside the if block.

var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

function FixedUpdate() {

// outside of (grounded) check, we will always accept
// movement input

moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;

if (grounded) {
// We are grounded, so leave this to prevent double-jumping

if (Input.GetButton ("Jump"))
{
moveDirection.y = jumpSpeed;
}
}

// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;

// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags  CollisionFlags.CollidedBelow) != 0;
}

@script RequireComponent(CharacterController)

Hope that helps, and also in future posts use things like Quote and Code in your posting to help the readability.

Thanks for the advice, I’m quite new to unity3d and scripting. :slight_smile:

However I tried your idea before, and the jump function stops working correctly or rather, the character only jumps a tiny bit…

I’ve been looking for tutorials for a few days now, trying to understand and trying different things.

How would a simplified jump/gravity script look, when using Character Controller?

This would be a huge help to me.

DOH! Sorry about that :sweat_smile: …what I get for writing quickly. Try this, and also try to understand how this is different than my first example:

moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);

if (grounded)
{
// We are grounded, so leave this to prevent double-jumping

   if (Input.GetButton ("Jump"))
   {
      moveDirection.y = jumpSpeed;
   }
}

// in my first example, this next line was not being executed
// after jumpSpeed was set, and that is why your
// character was only jumping slightly

moveDirection *= speed;

thanks again… If I’m doing this right, it seems to me that it results in a very slow gravity and an unsmooth jump.

Here’s a simple game I made where i need the cubes to be controlable in the air.
http://cubeattack.com/ (movement = a,d,w,space h,k,.)
jumping on the cubes makes them loose lifes)

I understand that the problem is that the code checks to see if the object is grounded, to enable movement.

Another lesson :slight_smile: I need to run my own examples.

Try this. Has a nice effect in my editor, and should be the ticket! Sorry for the bogus other examples…

var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;
private var lastYSpeed : float = 0;

function FixedUpdate() {
   if (grounded)
   {
      // We are grounded, so recalculate movedirection directly from axes
      moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
      moveDirection = transform.TransformDirection(moveDirection);
      moveDirection *= speed;
      
      if (Input.GetButton ("Jump")) {
         moveDirection.y = jumpSpeed;
      }
      
      // On the ground
      lastYSpeed = 0;
   }
   else
   {
   	  // We are in the air, maintain lastYSpeed
   	  moveDirection = new Vector3(Input.GetAxis("Horizontal"), lastYSpeed, Input.GetAxis("Vertical"));
      moveDirection = transform.TransformDirection(moveDirection);
      
      // Remove speed factor from influencing Y value
      moveDirection.x *= speed;
      moveDirection.z *= speed;
   }

   // Apply gravity
   moveDirection.y -= gravity * Time.deltaTime;
   lastYSpeed = moveDirection.y;
   
   // Move the controller
   var controller : CharacterController = GetComponent(CharacterController);
   var flags = controller.Move(moveDirection * Time.deltaTime);
   grounded = (flags  CollisionFlags.CollidedBelow) != 0;
}

@script RequireComponent(CharacterController)

Awesome! thanks alot… :smile: that’s what I’ve been trying to achieve…
Cheers!