C# 如何同时倒计时冷却时间和持续时间

C# 如何同时倒计时冷却时间和持续时间,c#,unity3d,2d,repeat,ienumerator,C#,Unity3d,2d,Repeat,Ienumerator,在我正在开发的一个小型模拟游戏(a.I.spaceship shooter)中,我试图想出一个有效的屏蔽函数或IEnumerator,它可以被调用或启动并执行多种操作: 如果护盾冷却时间高于零,则倒计时护盾冷却时间 如果冷却结束,在设定的持续时间(5秒)内激活防护罩 持续时间到期时停用防护罩 但是,我在尝试使用Ienumerator时遇到了一些问题。之前我已经能够使用IEnumerators来倒计时和冷却,但尝试同时进行冷却和持续时间似乎不起作用,因为Unity不允许我在不离开IEnumer

在我正在开发的一个小型模拟游戏(a.I.spaceship shooter)中,我试图想出一个有效的屏蔽函数或IEnumerator,它可以被调用或启动并执行多种操作:

  • 如果护盾冷却时间高于零,则倒计时护盾冷却时间
  • 如果冷却结束,在设定的持续时间(5秒)内激活防护罩
  • 持续时间到期时停用防护罩
但是,我在尝试使用Ienumerator时遇到了一些问题。之前我已经能够使用IEnumerators来倒计时和冷却,但尝试同时进行冷却和持续时间似乎不起作用,因为Unity不允许我在不离开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;
    }
每隔一秒钟左右,如果船还活着,我们有目标

我确实认为我目前不推荐使用IEnumerator,因为它至少每秒钟都要被调用一次,但由于目前环境非常小,这似乎不是一个问题


非常感谢您的帮助。

无需协同程序即可快速编写代码,不知道它在游戏中是否有效。我希望这会给你一些想法

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
}

}

Fire bullets状态不是等待时间,所以您将在一个框架中激发所有bullet。您如何调用您的协同程序?另外,请为盾牌添加
IEnumerator
。@derHugo我在问题中添加了一些额外的代码,看看这是否有用。我的问题是:这是只在
OnTriggerEnter
中调用一次,还是像在
Update
中那样调用每一帧?@derHugo它是在调用函数的invokereepeating中调用的
Shoot()
确定飞船是否在目标射程内,且当前未射击。该函数大约每秒重复一次。
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
}

}