C# Movement Script Problem (crouch speed is faster than normal speed, even when set to lower!)

I’m working on a rather simplistic movement script that’s attached to a cube to make it move around. I have three seperate variables for normal speed, running speed, and crouching speed. Normal is set to 0.2f, running to 0.4f, and crouching to 0.1f. The script below should make it so that crouching speed is one half of normal speed but instead it speeds of slightly when ctrl is pressed along with any of the movement keys! Anyone have a solution? Heres the c# script:

using UnityEngine;
using System.Collections;

public class movementScript : MonoBehaviour {
	
	public float speed;
	public float runSpeed;
	public float crouchSpeed; // will be subtracted form normal 'speed' to get crouchspeed

	public float jumpForce;
	public bool runOn = true;
	public bool crouchOn = true;
	bool canJump = true;
	bool isCrouching = false;

	public GameObject selectedGameObject;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	private void Update () {
		
		if (Input.GetKey (KeyCode.D)) {  // normal walking
			transform.position += transform.right * speed;
		}
		if (Input.GetKey (KeyCode.A)) {
			transform.position += -transform.right * speed;
		}
		if (Input.GetKey(KeyCode.W)){
			transform.position += transform.forward * speed;
		}
		if (Input.GetKey(KeyCode.S)){
			transform.position += -transform.forward * speed;
		}
		if (Input.GetKey (KeyCode.W) && Input.GetKey (KeyCode.LeftShift) && runOn == true){  // running
			transform.position += transform.forward * runSpeed;
		}
		if (Input.GetKey (KeyCode.A) && Input.GetKey (KeyCode.LeftShift) && runOn == true){
			transform.position += -transform.right * runSpeed;
		}
		if (Input.GetKey (KeyCode.D) && Input.GetKey (KeyCode.LeftShift) && runOn == true){
			transform.position += transform.right * runSpeed;
		}
		if (Input.GetKey (KeyCode.S) && Input.GetKey (KeyCode.LeftShift) && runOn == true){
			transform.position += -transform.forward * runSpeed;
		}
		if (Input.GetKey (KeyCode.W) && Input.GetKey (KeyCode.LeftControl) && crouchOn == true){  // crouching
			transform.position += transform.forward * crouchSpeed;
		}
		if (Input.GetKey(KeyCode.D) && Input.GetKey (KeyCode.LeftControl) && crouchOn == true){
			transform.position += transform.right * crouchSpeed;
		}
		if (Input.GetKey (KeyCode.A) && Input.GetKey (KeyCode.LeftControl) && crouchOn == true){
			transform.position += -transform.right * crouchSpeed;
		}
		if (Input.GetKey (KeyCode.S) && Input.GetKey (KeyCode.LeftControl) && crouchOn == true){
			transform.position += -transform.forward * crouchSpeed;
		}


		if (Input.GetKeyDown(KeyCode.Space) && canJump){
			rigidbody.AddForce(0, jumpForce, 0);
			canJump = false;
		}
		if (Input.GetKey (KeyCode.LeftControl)) {             // temporarily gets rid of top box collider on player
						selectedGameObject.SetActive (false); // there should be two box colliders connected to an empty
				} else {                                      // when the top one is temporarily deleted, the player is able to crouch
						selectedGameObject.SetActive (true);
		}

	}


	void OnCollisionEnter (Collision foo) // is the ground there? for jumping
	{
		canJump = true;
	}

}

Ditto what @getyour411 says above, transform.position gets two “+=” calls.

Say you’re holding down the D key to move right, and the CTRL key to crouch. Then both:

(Input.GetKey (KeyCode.D))

and

(Input.GetKey(KeyCode.D) && Input.GetKey (KeyCode.LeftControl) && crouchOn == true)

are true. Which means you’re adding the normal speed and the crouch speed both. Might I suggest refactoring to both make it clear what’s getting added and to make the script more maintainable? How about this:

private void Update () 
	{
		float currentSpeed = speed;
		if(Input.GetKey (KeyCode.LeftShift) && runOn == true)
		{
			currentSpeed = runSpeed;
		}
		if(Input.GetKey (KeyCode.LeftControl) && crouchOn == true)
		{
			currentSpeed = crouchSpeed;
		}

		if (Input.GetKey (KeyCode.D)) {
			transform.position += transform.right * currentSpeed;
		}
		if (Input.GetKey (KeyCode.A)) {
			transform.position += -transform.right * currentSpeed;
		}
		if (Input.GetKey(KeyCode.W)){
			transform.position += transform.forward * currentSpeed;
		}
		if (Input.GetKey(KeyCode.S)){
			transform.position += -transform.forward * currentSpeed;
		}

		if (Input.GetKeyDown(KeyCode.Space) && canJump){
			rigidbody.AddForce(0, jumpForce, 0);
			canJump = false;
		}
		if (Input.GetKey (KeyCode.LeftControl)) { // temporarily gets rid of top box collider on player
			selectedGameObject.SetActive (false); // there should be two box colliders connected to an empty
		} else { // when the top one is temporarily deleted, the player is able to crouch
			selectedGameObject.SetActive (true);
		}
	}