Crouching

Okay. I am still absurdly inexperienced in matters of scripting and such. I’m trying to add basic crouching functionality to the FPS Walker. After trying for quite a while, and lots of searching the scripting documentation, I figured out how to change the height of the character controller when “x” is pressed. However, I can’t figure out how to return it to it’s normal size when the key is released. At least I coded something that half-works :wink: .

var crouchHeight = 0.8;

function FixedUpdate() {
	
	if (Input.GetButtonDown ("Crouch")) {
	var controller : CharacterController = GetComponent(CharacterController);
	controller.height = crouchHeight * Time.deltaTime;
	}
}

[/code]

“Input.GetButtonUp” is on it’s way shortly. However, most FPS games don’t make you hold down the “crouch” button while you’re crouched. You should script a conditional statement to handle which crouch/standing state you’re in and if “crouch” is triggered then switch between the two states.

Wait… why would you be multiplying the crouch height by Time.deltaTime? Not only will that result in an EXTREMELY small value for the height, it would fluctuate wildly based on the framerate.

var crouchHeight = 0.8; 
var standingHeight = 1.5;
var crouching = false;

function FixedUpdate() { 
    
   if (Input.GetButtonDown ("Crouch")) crouching = !crouching;
   var controller : CharacterController = GetComponent(CharacterController); 
   if (crouching) controller.height = crouchHeight;
   else controller.height = standingHeight;
   
//down here you should probably move the camera as well to reflect the crouching status
}

That’s good to hear.

Well, actually, they do. Or at least most of the ones I’ve played.

That was me trying to avoid “snapping”. The intent is for the camera to move down and not toggle instantaneously between positions.

I have the toggle functionality working (as a temp solution), but when you toggle crouch off half the character controller gets stuck in the ground. This shows just what a programming novice I am, but I just don’t know how to move the controller straight up.

Thanks for responding

Just modify transform.position.y - Add to it (standingHeight - crouchHeight) / 2

Hi Reznic,

I like the ability toggle instantaneously between positions. (I guess I crouch faster than others.) This is my FPSWalker script:

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

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);
		
		// crouch is 1/3 speed
		if (crouch) 
		{
		moveDirection *= (speed / 3);
		}
		else
		{
		moveDirection *= speed;
		}
		
		if (Input.GetButton ("Jump")) 
		{
			moveDirection.y = jumpSpeed;
		}
		
		if (Input.GetButton ("Crouch")) 
		{
			if (!crouch)
			{
			GetComponent(CharacterController).height = 1.2;
			Camera.main.transform.Translate ( 0, -0.3, 0);
			crouch = true;
			}
		}
		else
		{
			if (crouch)
			{
			transform.Translate ( 0, 0.3, 0);
			GetComponent(CharacterController).height = 1.8;
			Camera.main.transform.Translate ( 0, 0.3, 0);
			crouch = false;
			}
		}
	}

	// 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;
}

function Awake ()
{
	var controller : CharacterController = GetComponent(CharacterController);
	if (!controller)
		gameObject.AddComponent("CharacterController");
}

I hope this helps,

JJ

I fixed it up so you have a smooth motion when getting back up and it wont ever let you fall through the floor either.

Here is the code:

var isCrouched : boolean = false;
var tryingtostand : boolean = false;
var controller : CharacterController;
var walker : FPSWalker;
controller = GetComponent(CharacterController);
walker = GetComponent(FPSWalker);
var keytimer=0;
function Update () {
keytimer++;
if(keytimer>10){

   if(Input.GetButton("crouch")) {
   keytimer=0;
			if(!isCrouched){
				walker.gravity=30;
				tryingtostand=false;
				crouch();
			}  else  {
				if(!tryingtostand){
					stand();
				}
			}
	}
}
	
	if(tryingtostand){
			if(controller.height<2){   
				controller.height += 3 * Time.deltaTime;
				transform.position.y += 1.1*Time.deltaTime;
				walker.gravity=0;
			} else {
				controller.height = 2;
				walker.gravity=30;
				tryingtostand=false;
			}
	}
}

function crouch() {
   controller.height = .5;
   isCrouched = true;
}

function stand(){
if(!tryingtostand){ 
isCrouched = false;
tryingtostand=true; 
}
}

The “keytimer” stuff is because for some reason my system has been having trouble with anything that needs to toggle using a keypress on the keyboard. It sends the key press wayyy too many times per millisecond etc. So if you press the key like normal it registers as you pressing it 4 times or so lol. I was having to quick touch keys to make things work… I got sick of this so I made that little keytimer deal to correct it.

You can change around the values to fit your own setup in regards to height when standing and crouching… also speed values for getting back up. I tend to like realism too so I kept them fairly slow.

I had it turn off the gravity for three reasons:

This prevents the player from having any chance of falling through the floor.
It Makes the motion much smoother (I did it with the gravity still on and it worked but was a touch jumpy sometimes because of the gravity fighting the transform position).
It is also easier to change the math, heights, and speeds later on without worrying about oddities.

I am going to have the player lose speed while crouched for mine here and you will probably do the same… for that we would just need to add:

walker.maxspeed= whatever;

I use maxspeed in mine because my walker script is custom and has speed ramping and dynamic changes for stamina and all sorts of things. The basic form would be to just use walker.speed and change it back when not crouched etc.

Also note that this will work regardless of where the player started out height wise (on the floor… standing on a box…wherever ). In other words… the code posted above my post deals with specific coordinates in space on the y axis… but … what if you used that code and tried to crouch while standing on a box in the game?.. It wouldn’t work and would cause issues. It is best to try and be dynamic whenever you can usually. It makes things smoother later on.

Have fun!!!

NAAH its not fucking working.