[Fixed]Run limit with energy and recovery

I have a script to make my character slower if he has less energy and to recover the enrgy while walking and crouching. I’ve fixed it.
Here’s the script.

var walkSpeed : float = 5;
var crchSpeed : float = 3;

static var stamina : float = 40;
var drainSpeed : float = 1.5;
var crouchRecovery : float = 1.5;
var walkRecovery : float = 1;

static var walking : boolean = true;
static var running : boolean = false;
static var crouched : boolean = false;
static var moving : boolean = false;
static var cantMove : boolean = false;
 
private var Speed : float = 1;
private var chMotor: CharacterMotor;
private var ch: CharacterController;
private var tr: Transform;
private var height: float;
 
function Start(){
    chMotor = GetComponent(CharacterMotor);
    tr = transform;
    ch = GetComponent(CharacterController);
	height = ch.height;
}
 
function Update(){
 
    var h = height;
    var speed = Speed;
    var runSpeed : float = stamina/4;
    
    if (cantMove){
	    Time.timeScale = 0.0;
    }else{
		Time.timeScale = 1.0;
    }
    if (Input.GetButton("Jump")){
	    crouched = false;
    }
    if (Input.GetKey("left shift") || Input.GetKey("right shift")){
		running = true;
	}else{
		running = false;
	}
	if (Input.GetAxis("Horizontal") || Input.GetAxis("Vertical")){
		moving = true;
	}else{
		moving = false;
	}
	if (!running && !crouched){
		speed = walkSpeed;
	    walking = true;
    }else{
	    walking = false;
    }
    if (Input.GetKeyDown(KeyCode.LeftControl) || Input.GetKeyDown(KeyCode.RightControl)){
	    crouched = !crouched;
    }
    if (crouched){
        h = 0.5 * height;
        speed = crchSpeed;
    }
    if (running && moving){
		Draining();
		speed = runSpeed;
		crouched = false;
	}else{
		Recovering();
	}
	if (stamina<24){
		audio.Play();
	}
    chMotor.movement.maxForwardSpeed = speed;
    chMotor.movement.maxSidewaysSpeed = speed -0.5;
    chMotor.movement.maxBackwardsSpeed = speed -1;
    var lastHeight = ch.height;
    ch.height = Mathf.Lerp(ch.height, h, 5*Time.deltaTime);
    tr.position.y += (ch.height-lastHeight)/2;
}

function Draining(){
	stamina -= drainSpeed * Time.deltaTime;
	if (stamina <= 24){
		stamina = 24;
		audio.Play();
	}
}

function Recovering(){
    if (walking && !moving){
		stamina += walkRecovery * Time.deltaTime;
	}
	if (crouched && !moving){
		stamina += crouchRecovery * Time.deltaTime;
	}
	if (walking){
		stamina += 0.5 * walkRecovery * Time.deltaTime;
	}
	if (crouched){
		stamina += 0.5 * crouchRecovery * Time.deltaTime;
	}
	if (stamina >= 40){
		stamina = 40;
	}
}

These lines of yours are just stamina=0 (it spins during 1 frame until stamina drops to 0 or less):

while (stamina>0)
  stamina -= drainStamina*Time.deltaTime;

It takes a little to get used-to Update being a loop already. The stamina-= line is running 60 times/sec, so you don’t need the while loop. Just about all of your “whiles” should be “ifs”.

Then general programming tips: figure out something small you can write and test. In your case, maybe just write the part where stamina determines run speed. Don’t ever change stamina. Then just run and manually change stamina to see if it works. Then add just one more easy to test thing (gaining stamina, and start at 0? Try running with it 1/2-way recharged to see if it stops going up?)

Here is a function for draining I think should work (It’s not tested however). I don’t know about slowing though.

var walkSpeed : float = 7;
var runSpeed : float = 20;
var crchSpeed : float = 3;

static var walking : boolean = true;
static var running : boolean = false;

var stamina : float = 100;
var drainStamina : float = 10;
var recovery : float = 20;

static var crouched : boolean = false;
static var cantMove : boolean = false;
var testLight : Light;

functionStamina(){
     if(running && stamina > 0){
     stamina -= drainStamina * Time.deltaTime;
     }
     else if(walking && stamina < 100){
     stamina += recovery * Time.deltaTime;
     }

//some code for faster regen when still
   var moving : boolean;

   if(Input.GetAxis("Horizontal") || Input.GetAxis("Vertical")){
   moving = true;
   }
   else{
   moving = false
   }

var stillRecovery : float = 20.0; 

     if(!moving && stamina < 100){
     stamina += stillRecovery * Time.deltaTime
     }
//end of the regen code

//Slowing code
walkSpeed = stamina / 14.2; //14.2 because 100/14.2 = 7
}

function Update(){
Stamina(); //just add this in current function after removing current regeneration stuff
}