- Home /
Waiting twice inside coroutine (C#)
Hey guys, I am working on a system for changing weapons.
I need it to wait for the disarm animation to finish before playing the arm animation for the next weapon. However it does not make it to the Debug.Log statement as it exits the routine after the yield. Any other ideas on how to get the routine to wait twice?
using UnityEngine;
using System.Collections;
public class weaponManager : MonoBehaviour {
private bool busy = false;
public Transform currentWeapon;
public Transform[] weapons;
public int startWeapon = 1;
void Start(){
StartCoroutine(EquipWeapon(startWeapon));
}
void Update(){
if(!busy){
if(Input.GetKeyDown(KeyCode.Alpha1)){
StartCoroutine(EquipWeapon(1));
}else if(Input.GetKeyDown(KeyCode.Alpha2)){
StartCoroutine(EquipWeapon(2));
}else if(Input.GetKeyDown(KeyCode.Alpha3)){
StartCoroutine(EquipWeapon(3));
}
}
}
IEnumerator EquipWeapon(int weaponNumber){
busy = true;
if(currentWeapon != null && currentWeapon != weapons[weaponNumber - 1]){
Transform weapon;
weapon = currentWeapon;
weapon.GetComponent<weaponScript>().armed = false;
weapon.animation.Play("Disarm");
currentWeapon = weapons[weaponNumber - 1];
yield return WaitForAnimation(weapon);
Debug.Log("passed");
weapon = currentWeapon;
weapon.animation.Play("Arm");
yield return WaitForAnimation(weapon);
weapon.GetComponent<weaponScript>().armed = true;
}else if(currentWeapon == null){
Transform weapon = weapons[weaponNumber - 1];
weapon.animation.Play("Arm");
yield return WaitForAnimation(weapon);
weapon.GetComponent<weaponScript>().armed = true;
}
busy = false;
}
private static IEnumerator WaitForAnimation(Transform obj){
do{yield return null;}while(obj.animation.isPlaying);
}
}
Answer by Key_Less · Jan 03, 2014 at 12:12 AM
Try yielding for the duration of the animation inside the EquipWeapon coroutine itself.
var clipLength = weapon.animation.GetClip("Disarm").length;
yield return new WaitForSeconds(clipLength);
// Do your stuff...
clipLength = weapon.animation.GetClip("Arm").length;
yield return new WaitForSeconds(clipLength);
I've tried that, it might work in javascript but im trying to stick to c#.
Whoops, just noticed I missed the 'new' and I've edited the answer. It's written in C# and should work like a charm :)
I did it with the "new" it runs the coroutine fine but returns after, im trying to pause the the routine without returning
It does return indeed, this is how coroutines work. At the yield instruction, control is returned back to Unity and any further execution of the coroutine is paused until the next frame. WaitForSeconds further delays any execution for the given time period and once the delay has been met, the coroutine will begin execution from the last executed yield instruction.
I would recommend reading this article on coroutines. There is a good example of a coroutine that waits for an animation to partially complete. It's written in JS but can very easily be converted into C# and modified so that it waits for the entire length of the animation.
If this doesn't sound like the desired result, then you may want to look else where other than coroutines.
Answer by rutter · Jan 02, 2014 at 11:53 PM
Close, but not quite right:
yield return WaitForAnimation(weapon);
Yielding on another coroutine has a tricky syntax in C#, since you need to use StartCoroutine()
:
yield return StartCoroutine(WaitForAnimation(weapon));
It doesn't pause the coroutine that calls it.
I'm trying to pause the same coroutine twice.
Your answer
Follow this Question
Related Questions
Yield Wait for Seconds (A little help here) 2 Answers
Why Won't My Coroutine Yield? 2 Answers
Returning an IEnumerator as an int? 1 Answer
What am I doing wrong with IEnumerator? 1 Answer
Turn bool on/off x time every few seconds in coroutine 2 Answers