Как отсчитать время восстановления и длительность - PullRequest
2 голосов
/ 01 июля 2019

В небольшой симуляционной игре (космический корабль А.И.), которую я разрабатываю, я пытаюсь придумать эффективную функцию щита или IEnumerator, которую можно вызывать или запускать, и выполнять несколько действий:

  • Обратный отсчет времени восстановления щита, если он выше нуля
  • Активировать щит на установленную продолжительность (5 секунд), если время восстановления истекло
  • Отключить щит по истечении срока действия

Тем не менее, я сталкиваюсь с некоторыми проблемами при попытке использовать только Ienumerator. Я был в состоянии использовать IEnumerators для обратного отсчета таймеров и перезарядок, но попытка выполнить как перезарядку, так и длительность, похоже, не работает, поскольку Unity не позволяет мне дважды подождать WaitForSeconds, не выходя из IEnumerator.

Аналогично, у каждого корабля есть турель, и внутри этой турели находится IEnumerator, который запускает или отсчитывает время восстановления, в зависимости от того, что требуется для ситуации.

// Fire continuously if in range and we have more than 1 shot left
    // Otherwise, reload for (rate) seconds and reset shots left
    public IEnumerator Fire(Vector2 target) {
        firing = true;

        if (cooldown <= 0) {
            if (bullets > 0) {
                // Fire a bullet
                bullets--;

                // Instatiate the bullet
                }
            } else {
                // Reload
                cooldown = rate;
                bullets = count;
            }
        } else {
            yield return new WaitForSeconds(1);
            cooldown--;
        }

        firing = false;
        yield break;
    }

Fire Coroutine вызывается с помощью флага firing, чтобы проверить, запущен он или нет, и если он не вызывается

var fire = turret.Fire(shootTarget + offset);
if (!turret.firing && InRange() == true) {
    StartCoroutine(fire);
}

каждую секунду или около того, если корабль жив и у нас есть цель.

Я думаю, что мое текущее использование IEnumerator не рекомендуется, потому что его нужно вызывать, по крайней мере, каждую секунду, но с учетом того, насколько мала среда в данный момент, это не проблема.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 01 июля 2019

Быстрый код без сопрограмм, не знаю, работает ли он в игре.Надеюсь, это должно дать вам некоторое представление.

public class Shield : MonoBehaviour {

public float duration;
public float cooldown;
public float lastActivated;
public bool IsActivated => (lastActivated - (Time.time - duration)) > 0;
public bool onCoolDown => (lastActivated - (Time.time - cooldown)) > 0;

public void Activate(){
if(onCoolDown) return;

lastActivated = Time.time;
}

void LateUpdate(){
if(IsActivated) //Show shield effects, blahblah
else //Do nothing, blahblah
}

}
...