Has 3 known bugs.
1) it's possible to rapidly crouch and cause yourself to drop through the floor.
2) it's easy to crouch yourself stuck in the doorframe and drop through the level when trying to crouch again.
3) the resulting crouch and stading height are not always precisely the same, but almost never noticeable.
I am really unsure why there is a problem dropping through the level, especially at the door.
I have nothing I can anchor the controller to. The controller height can be clamped between standingHeight and crouchingHeight as set in playerMotor. and a boolean can be set to true when one of those two limits are reached, and then the transform.position can be stopped too at the same time.
Using transform.localposition would be nice, but it does not work right because there is no parent transform for the controller.transform.
Code: Select all
public enum CrouchToggleAction
{
DoNothing,
DoStanding,
DoCrouching
}
public class Croucher : MonoBehaviour
{
private CrouchToggleAction toggleAction;
public CrouchToggleAction ToggleAction
{
get { return toggleAction; }
set { toggleAction = value; }
}
public float toggleActionSpeed;
private PlayerMotor playerMotor;
private CharacterController controller;
private float crouchHeight;
private float standHeight;
private void Start()
{
playerMotor = GetComponent<PlayerMotor>();
controller = GetComponent<CharacterController>();
standHeight = playerMotor.standingHeight;
crouchHeight = playerMotor.crouchingHeight;
toggleAction = CrouchToggleAction.DoNothing;
toggleActionSpeed = 12f;
}
// perform whatever action CrouchToggleAction is set to.
private void Update()
{
if (toggleAction == CrouchToggleAction.DoNothing)
return;
bool bFinished = false;
if (toggleAction != CrouchToggleAction.DoNothing)
{
float changePerUpdate = toggleActionSpeed * Time.deltaTime;
if (toggleAction == CrouchToggleAction.DoCrouching)
changePerUpdate = -1 * changePerUpdate; // reverse direction
controller.height = Mathf.Clamp(controller.height + changePerUpdate, crouchHeight, standHeight);
controller.transform.position += new Vector3(0, changePerUpdate / 2.0f);
if (toggleAction == CrouchToggleAction.DoCrouching)
bFinished = (controller.height <= crouchHeight);
else
bFinished = (controller.height >= standHeight);
}
if (bFinished)
{
//Debug.Log("Controller.height = " + controller.height);
Debug.Log("Controller.transform.position.y" + controller.transform.position.y);
toggleAction = CrouchToggleAction.DoNothing;
}
}
}