Hi everybody,
I have a script that allows the player to crouch, but it only lets the player crouch
when the key is down. How can I make it possible to let the player crouch after
he pressed ctrl once, and stand back up again if he presses ctrl again.
My crouching code:
var walkSpeed: float = 7; // regular speed
var crchSpeed: float = 3; // crouching speed
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float; // initial height
function Start(){
chMotor = GetComponent(CharacterMotor);
tr = transform;
ch = GetComponent(CharacterController);
height = ch.height;
}
function Update(){
var h = height;
var speed = walkSpeed;
if (Input.GetKey("left ctrl")){
h = 0.5 * height;
speed = crchSpeed;
}
chMotor.movement.maxForwardSpeed = speed; // set max speed
var lastHeight = ch.height; // crouch/stand up smoothly
ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
tr.position.y += (ch.height-lastHeight)/2; // fix vertical position
}
In Update() check for GetKeyDown(“left ctrl”) and make a bool toggle based on that. Then check for that bool instead of the Input event to adjust height and speed.
Ok so I did this, but it still doesn’t work…
var walkSpeed: float = 7; // regular speed
var crchSpeed: float = 3; // crouching speed
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float; // initial height
function Start(){
chMotor = GetComponent(CharacterMotor);
tr = transform;
ch = GetComponent(CharacterController);
height = ch.height;
}
function Update(){
var h = height;
var speed = walkSpeed;
var crouching : boolean = false;
if (Input.GetKey("left ctrl")){
if(!crouching){
crouching = true;
} else {
crouching = false;
}
}
if(crouching){
h = 0.5 * height;
speed = crchSpeed;
}
chMotor.movement.maxForwardSpeed = speed; // set max speed
var lastHeight = ch.height; // crouch/stand up smoothly
ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
tr.position.y += (ch.height-lastHeight)/2; // fix vertical position
}
Did you mean something else?
Yes, that’s why I wrote GetKeyDown() which works in a different way than GetKey(). 
GetKey(): http://docs.unity3d.com/Documentation/ScriptReference/Input.GetKey.html
“Returns true while the user holds down the key identified by name.”
GetKeyDown(): http://docs.unity3d.com/Documentation/ScriptReference/Input.GetKeyDown.html
“Returns true during the frame the user starts pressing down the key identified by name.”
Or to be more specific:
In your current model, your are basically toggling the crouch mode every single frame the left control key is pressed.
With GetKeyDown() however crouching is only toggled during that exact frame the left control key is pressed.
Ok, so I did change the getKey to getKeyDown, but now it doesn’t crouch at all:
var crchSpeed : float = 3;
var walkSpeed : float = 7;
var h = height;
var speed = walkSpeed;
var crouching : boolean = false;
if (Input.GetKeyDown("left ctrl")){
if(crouching){
crouching = false;
} else {
crouching = true;
}
}
if(crouching){
h = 0.5 * height;
speed = crchSpeed;
}
sorry… I might be a little bit noob…
Of course you still need to stick to Update()!
Basically you only needed to change line 23 of the code in your second post:
var walkSpeed: float = 7; // regular speed
var crchSpeed: float = 3; // crouching speed
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float; // initial height
function Start(){
chMotor = GetComponent(CharacterMotor);
tr = transform;
ch = GetComponent(CharacterController);
height = ch.height;
}
function Update(){
var h = height;
var speed = walkSpeed;
var crouching : boolean = false;
if (Input.GetKeyDown("left ctrl")){
if(!crouching){
crouching = true;
} else {
crouching = false;
}
}
if(crouching){
h = 0.5 * height;
speed = crchSpeed;
}
chMotor.movement.maxForwardSpeed = speed; // set max speed
var lastHeight = ch.height; // crouch/stand up smoothly
ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
tr.position.y += (ch.height-lastHeight)/2; // fix vertical position
}
It was still in the update function. I also tried copying your exact code, but it only goes down a little for like a half second, and then it goes back up again…
I tried doing
var walkSpeed: float = 7; // regular speed
var crchSpeed: float = 3; // crouching speed
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float; // initial height
function Start(){
chMotor = GetComponent(CharacterMotor);
tr = transform;
ch = GetComponent(CharacterController);
height = ch.height;
}
function Update(){
var h = height;
var speed = walkSpeed;
var crouching : boolean = false;
if (Input.GetKeyDown("left ctrl")){
if(!crouching){
crouching = true;
} else {
crouching = false;
}
}
if(crouching){
//h = 0.5 * height;
//speed = crchSpeed;
Debug.Log("crouching");
} else {
Debug.Log("Not crouching");
}
chMotor.movement.maxForwardSpeed = speed; // set max speed
var lastHeight = ch.height; // crouch/stand up smoothly
ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
tr.position.y += (ch.height-lastHeight)/2; // fix vertical position
}
but then it only showed “Crouching” exactly on the key press.
Do you know what’s wrong?
Ah, now I see. I missed line 20 in the script. You need to move that line to the outside of Update() to make it persistent, otherwise it tells Unity to reset the crouching state at the beginning of every frame - which is of course not what you want.
Quick point to help make your life easier. In C-like languages like Java and C#, you can shorten
if(!crouching){
crouching = true;
} else {
crouching = false;
}
to just
crouching = !crouching;
Just hoping to save you some future typing. 