- Home /
help with character controller crouching
Hi I am using a character controller for a 2D game and have come across a problem I am sure many have had. I currently have the "s" setup to make my player crouch. What I did was make the controller.height 1.5 when I crouch and 2 when I don't. The problem is that when I let go of "s" to stand up I fall through the floor. When my controller grows back to 2 his capsule goes through the floor a little so unity just makes him fall right through. What is the best method to solve this problem while making sure it doesn't look bad during gameplay. Thank you in advance for any response.
if (Input.GetKey("s"))
{
crouching = true;
controller = GetComponent(CharacterController);
controller.height = 1.5;
}
else if (Input.GetKeyUp("s"))
{
crouching = false;
controller = GetComponent(CharacterController);
controller.height = 2.0;
}
The best resource for crouching and running with the Character Controller : http://answers.unity3d.com/questions/164638/how-to-make-the-fps-character-controller-run-and-c.html
While GetComponent is now running faster, you really should store a reference to the controller at start (ins$$anonymous$$d of every frame while S is pressed or released)
var controller : CharacterController;
function Start()
{
controller = GetComponent(CharacterController);
}
I actually have var controller : CharacterController; up top at the very beginning of my script in line 1. It is currently not in any function. Do you recommend moving it to Start(). I tried to put it in Start once but couldn't,
Find and store a reference to the Character Controller at Start, ins$$anonymous$$d of in the input conditionals :
var controller : CharacterController;
function Start()
{
controller = GetComponent(CharacterController);
}
function DoStuff()
{
if (Input.Get$$anonymous$$ey("s"))
{
crouching = true;
controller.height = 1.5;
}
else if (Input.Get$$anonymous$$eyUp("s"))
{
crouching = false;
controller.height = 2.0;
}
}
The problem you're having is when the collider is scaled up, it needs to be raised up by half the scaleY value. So the collider is not penetrating the collider below it when it is scaled up. Check the link in my first comment, answer by Aldo, Edited 2.
cool thanks that's what I needed to learn about character controller at start. Now to check out that link.
This is the line that is doing all the work, to raise the character controller up when it is scaled up, keeping the collider above the collider it is standing on :
tr.position.y += ( ch.height - lastHeight ) / 2; // fix vertical position
You should also look at how the scale is lerped rather than being instantly changed.
Answer by AlucardJay · Jun 21, 2013 at 05:25 AM
Answer from my comments :
The best resource for crouching and running with the Character Controller : http://answers.unity3d.com/questions/164638/how-to-make-the-fps-character-controller-run-and-c.html
While GetComponent is now running faster, you really should store a reference to the controller at start (instead of every frame while S is pressed or released)
Find and store a reference to the Character Controller at Start, instead of in the input conditionals :
var controller : CharacterController;
function Start()
{
controller = GetComponent(CharacterController);
}
function DoStuff()
{
if (Input.GetKey("s"))
{
crouching = true;
controller.height = 1.5;
}
else if (Input.GetKeyUp("s"))
{
crouching = false;
controller.height = 2.0;
}
}
The problem you're having is when the collider is scaled up, it needs to be raised up by half the scaleY value. So the collider is not penetrating the collider below it when it is scaled up. Check the link in my first comment, answer by Aldo, Edited 2.
This is the line that is doing all the work, to raise the character controller up when it is scaled up, keeping the collider above the collider it is standing on :
tr.position.y += ( ch.height - lastHeight ) / 2; // fix vertical position
You should also look at how the scale is lerped rather than being instantly changed.
I have stripped out the parts you want, and renamed some of the variables :
#pragma strict
private var ch : CharacterController;
private var startHeight : float; // initial height
function Start()
{
ch = GetComponent(CharacterController);
startHeight = ch.height;
}
function Update()
{
var newH : float = startHeight; // new height variable
// press C to crouch
if ( Input.GetKey("c") )
{
// calculate new height
newH = 0.5 * startHeight;
}
// crouch/stand up smoothly
var lastHeight = ch.height;
// lerp CharacterController height
ch.height = Mathf.Lerp( ch.height, newH, 5.0 * Time.deltaTime );
// fix vertical position
transform.position.y += ( ch.height - lastHeight ) * 0.5;
}
Here is the process :
new height = start height
if crouching, new height = start height * 0.5
last height is the current character controller height
lerp the character controller height between the current height and the new height (crouch/stand smoothly)
add to the position Y : the current lerped height - the height before lerping, divided by 2
so if the character grows 0.1 in height, add 0.05 to the position Y
or if the character shrinks by 0.1 in height, minus 0.05 to the position Y
thanks a lot brother you just added the final piece to my player script puzzle.