state change with button but falls back to previous

Hi,
I’m currently working on a little game and I want to change states for my character. So, when he is idle and I press certain buttons, he changes state to walking or jumping and so on. I want him to be able to pickup boxes, so there is a state “pickup” and “putdown”. But here is my problem:

when he is idle, and i press F he changes to pickup. Then he waits 2.5s until he goes to idlecarry (idle and carrying a box). But when I then press G (button to put sth down) he only switches to the putdown state for a brief moment, before changing back to idlecarry. But he shouldnt be able to. Here is the relevant code (I stripped it to the important parts, but the bug still appears):

function Update()
{
   MoveType ();
   print(state);
}
function MoveType ()		
{

	if(state == State.idle)
	{
		if(Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0)
		{
			state = State.walking;
			moveSpeed = walkSpeed;
		}
		else if(Input.GetButton("Jump"))
		{
			state = State.jumping;
		}
		else if(Input.GetButton("Pickup"))
		{
			//if(box.nearPlayer)
			//{
				state = State.pickup;
			//}
		}
	}
	if(state == State.pickup)
	{
		yield WaitForSeconds (2.5);
		state = State.idlecarry;
	}

	if(state == State.idlecarry)
	{
		if(Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0)
		{
			state = State.walkcarry;
			moveSpeed = walkcarrySpeed;
		}
		else if(Input.GetButton("Putdown"))
		{
			state = State.putdown;
		}
	}
	if(state == State.putdown)
	{
		yield WaitForSeconds (1.5);
		state = State.idle;
	}
}

So technically I think, that once in State.putdown, it shouldnt change back to State.idlecarry. Or what am I doing wrong?

I think I fixed it.
I think the yield function causes some problems with the if statements. Tried it with switch/case, but it had the same behaviour.

now, when I go into pickup or putdown, the according animation is playing.
the state then changes to idlecarry or idle, when the animation is finished. this kind of works.

so yeah, I think, that the yield function was the problem. Movement() is commented out, so I could focus on the state problem.And the comments are in general german, sry
But here is the script how it is right now:

#pragma strict

//scriptvariablen
var jumpForce: float;
var gravity: int;

var walkSpeed: float;
var runSpeed: float;
var walkcarrySpeed: float;

var rotateSpeed: int;

var walkAnimSpeed: float;
var runAnimSpeed: float;
var walkcarryAnimSpeed: float;

//ANIMATIONS
var idleAnimation_1: AnimationClip;
var idleAnimation_2: AnimationClip;
var idleAnimation_3: AnimationClip;
var idleAnimation_4: AnimationClip;
var walkAnimation: AnimationClip;
var runAnimation: AnimationClip;
var jumpAnimation: AnimationClip;	//TO ANIMATE
var fallAnimation: AnimationClip;	//TO ANIMATE

var idleCarryAnimation: AnimationClip;
var walkCarryAnimation: AnimationClip;

var pickupAnimation: AnimationClip;
var putdownAnimation: AnimationClip;	//TO ANIMATE

var pushAnimation: AnimationClip;

//SONSTIGES


var box: BoxPickup;


private var charController: CharacterController;

@HideInInspector	//Hides the next variable
public var state: State;
public enum State
{
	idle,
	walking,
	running,
	jumping,
	
	idlecarry,
	walkcarry,
	
	pushing,
	pickup,
	putdown,
	
	falling,

}
//FLOAT
private var moveSpeed: float;
private var fallForce:int;

//VECTOR3
private var camForward: Vector3;
private var camRight: Vector3;

private var movement:Vector3;

function Start () 
{
	//assign CharacterController zu, charController automatisch
	charController = GetComponent(CharacterController);
	state = State.idle;
}

function Update ()
{
	GetCam ();	//Cam() aufrufen um Kameraausrichtung zu erhalten
		
	MoveType();		//Bewegungstyp aufrufen
		
	
	
	//Movement ();	
	Animations();	//Animation aufrufen
	print("State: " + state);
}

//wie bewegt sich der player?
function MoveType ()		//HIER IRGENDWAS MIT DEN IDLE UND CARRY STATES MACHEN!
{
	switch(state)
	{
		//IDLE
		case State.idle:
			if(Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0)
			{
				state = State.walking;
			}
			else if(Input.GetButton("Jump"))
			{
				state = State.jumping;
			}
			else if(Input.GetButton("Pickup"))
			{
				state = State.pickup;
			}
			break;
		//WALKING	
		case State.walking:
			if(Input.GetAxis("Horizontal")==0 && Input.GetAxis("Vertical")==0)
			{
				state = State.idle;
			}
			else if(Input.GetButton("Run"))
			{
				state = State.running;
			}
			else if(Input.GetButton("Jump"))
			{
				state = State.jumping;
			}
			break;
		//RUNNING	
		case State.running:
			if(Input.GetAxis("Horizontal")==0 && Input.GetAxis("Vertical")==0)
			{
				state = State.idle;
			}
			else if(!Input.GetButton("Run"))
			{
				state = State.walking;
			}
			else if(Input.GetButton("Jump"))
			{
				state = State.jumping;
			}
			break;
		//IDLECARRY	
		case State.idlecarry:
			if(Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0)
			{
				state = State.walkcarry;
			}
			else if(Input.GetButton("Pickup"))
			{
				state = State.putdown;
			}
			break;
		//WALKCARRY
		case State.walkcarry:
			if(Input.GetAxis("Horizontal")==0 && Input.GetAxis("Vertical")==0)
			{
				state = State.idlecarry;
			}
			break;
		//PICKUP	
		case State.pickup:
			if(!animation.isPlaying)
			{
				state = State.idlecarry;
			}
			break;
		//PUTDOWN	
		case State.putdown:
			if(!animation.isPlaying)
			{
				state = State.idle;
			}
			break;		
	}
}


function Movement ()
{
	if(charController.isGrounded) //fallForce auf Null setzen, wenn grounded
	{
		fallForce = 0;
	}
	else if(!charController.isGrounded)
	{	
		if(state == State.jumping)	//wenn char not grounded aber jumping dann erst steigen, dann senken
		{
			var jumpDirection = (transform.up * (jumpForce + fallForce));
			fallForce -= gravity;
		}
		else	//ansonsten sollte er nur runterfallen
		{
			//state = State.falling;
			var fallDirection = (transform.up * fallForce);
			fallForce -= gravity;
		}
	}
	//wenn pickup oder putdown, nicht bewegen können!
	if(state != State.pickup && state != State.putdown)
	{
		//achseninput, wo soll er hin?
		var h = Input.GetAxisRaw("Horizontal");
		var v = Input.GetAxisRaw("Vertical");
	
		var moveDirection = (h*camRight + v*camForward).normalized;	//bewegungsrichtung berechnen als vector anhand vom input und dann normalisieren
		
		if(Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
		{
			var targetDirection = Quaternion.LookRotation(moveDirection);	//2 zeilen, guck dahin wo du hin willst
			transform.rotation = Quaternion.Slerp(transform.rotation, targetDirection, Time.deltaTime * rotateSpeed);
		}
		//tatsächliche bewegung pro sekunde
		movement = (moveDirection * moveSpeed + (jumpDirection + fallDirection))*Time.deltaTime;
		
		//BEWEGE DICH DU SAU!
		charController.Move(movement);	
	}
	
}

// laufgeschwindigkeit und animationen zuordnen

//ALLES IN SWITCH STATEMENT REIN!
function Animations ()
{
	switch(state)
	{
		case State.idle:
			var random:float;
			if (!animation.isPlaying)
			{
				random = Random.value;
				Debug.Log("idle: "+random);
				
				if(random <= 0.7)
				{
					animation.CrossFade(idleAnimation_1.name);
				}
				else if(random > 0.7 && random <= 0.8)
				{
					animation.CrossFade(idleAnimation_2.name);
				}
				else if(random > 0.8 && random <= 0.9)
				{
					animation.CrossFade(idleAnimation_3.name);
				}
				else if(random > 0.9 && random <= 1)
				{
					animation.CrossFade(idleAnimation_4.name);
				}
			}
			break;
			
		case State.idlecarry:
			animation.CrossFade(idleCarryAnimation.name);
			break;
			
		case State.pickup:
			animation.Play(pickupAnimation.name);
			break;
			
		case State.putdown:
			animation.Play(putdownAnimation.name);
			break;
	}

}

function GetCam ()
{
	//lokalen z Vector Global machen. Dann y-Komponente auf 0 setzen.
	var camRelFwd:Vector3 = Camera.main.transform.TransformDirection(Vector3.forward);
	camForward = Vector3(camRelFwd.x, 0, camRelFwd.z);
	
	camRight = Vector3(camForward.z , 0 , -camForward.x);
}

Im not very good at javascript.

in C# you have to start the yield function using StartCoroutine (Javascript does this automatically)

Basically it saves a variable each time it starts a yield function telling the program to come back and finish the function after a certain amount of time.
(I read this on a Unity answers. Unfortunately I cant find it.)

When you yield in the Update function. It will be saving a new variable telling it to come back and finish the function at a later date.

When state == state.pickup the program will continue to create variables telling the program to come back and finish for 2.5 seconds until it returns and changes the state back to idlecarry. But then it will continue returning for a further 2.5 seconds meaning it will contine changing the state to idle carry each frame for a further 2.5 seconds.

This is unless there’s some Unity Javascript magic I’m unaware off.