yield return null не продолжает работу корутины
Хочу сделать тряску камеры после убийства врага, но функция проходит цикл while 1 раз (не зависимо от времени) и бесконечно ожидает yield return null. Вот код корутины
public IEnumerator ShakeCamera(float duration, float magnitude)
{
Vector3 originalpos = new Vector3(0,0,0);
float elapsed=0.0f;
while (elapsed<duration)
{
float x = Random.Range(-1f, 1f) * magnitude;
float y = Random.Range(-1f, 1f) * magnitude;
transform.localPosition = new Vector3(x, y,0f);
elapsed += Time.deltaTime;
print(elapsed);
yield return null;
}
transform.localPosition = originalpos;
}
и код врага, вызывающий эту корутину
public void TakeDamage(int damage)
{
health -= damage;
if (health <= 0)
{
Object.Destroy(gameObject);
StartCoroutine(CamShake.ShakeCamera(0.15f, 1f));
}
}
Ответы (4 шт):
yield return null стоит в нужном месте, что бы продолжить после прохода текущей итерации цикла Update. У меня подобная проблема была, вызвана она уничтожением GameObject, в вашем случае в этой строке Object.Destroy(gameObject); Но как решить эту проблему я не знаю, я просто переделал код и убрал у себя Destroy(gameObject); P.S. В моей 2d игре CameraShake вызывается через анимацию
Извините за беспокойство, камера не двигалась из-за пустой анимации на ней
Повторил глюк (Unity 19.4.14LTS):
Debug.Log("1");
float iceDuration = 0.5f;
Destroy(ice = Instantiate(Ice, new Vector3(transform.position.x, transform.position.y + 1.5f, transform.position.z), Quaternion.Euler(transform.eulerAngles)), iceDuration);
ice.transform.parent = gameObject.transform;
Debug.Log("2");
yield return new WaitForSeconds(iceDuration*2f);
Debug.Log("3"+currentState);
if (currentState == allStates[IdleState])
{
Run();
}
После любого использования Destroy (даже не текущего объекта) корутины не продолжаются. В моём примере "3" не появится никогда. Отсрочил всё нужное с использованием другой корутины:
Debug.Log("1");
float iceDuration = 0.5f;
Idle();
StartCoroutine(IdleStateRelease(iceDuration));
Destroy(ice = Instantiate(Ice, new Vector3(transform.position.x, transform.position.y + 1.5f, transform.position.z), Quaternion.Euler(transform.eulerAngles)), iceDuration);
ice.transform.parent = gameObject.transform;
Debug.Log("2");
}
private IEnumerator IdleStateRelease(float iceDuration)
{
yield return new WaitForSeconds(iceDuration * 2f);
Debug.Log("3" + currentState);
if (currentState == allStates[IdleState])
{
Run();
}
}