您所请求的是使用协程的基于状态的引擎。对于这种情况,有四个状态:
- 敌人淡入。
- 敌人等待玩家输入。
- 敌人淡出。
- 敌人获胜。游戏重新开始。
下面的代码是您发布的代码的修订版。我重构了
Start()
和
Update()
Monobehaviours,使它们仅专注于启动状态引擎和监视来自玩家的输入。
Start()
仅需要为将来在状态引擎中操作的敌人做准备,因此我使用该位置执行
EnemyFadeIn()
协程。
输入标志直到
Update()
才会被重置,因此建议所有输入调用都发生在Update循环中。这也是为什么从
Start()
Monobehaviour中删除了输入处理的原因。您可以在
Unity Input文章中找到更多信息。但是,您发布的代码中显示的所有剩余函数都可以平稳地运行在协程中。
using System.Collections;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
public float waitTime = 10.0f;
public float fadeTime = 3.0f;
public float betweenFadesTime = 2.0f;
public bool canRespond = false;
public bool hasResponded = false;
public GameObject enemy;
void Start()
{ StartCoroutine(EnemyFadeIn(fadeTime, betweenFadesTime, waitTime)); }
void Update() {
if ((Input.GetKeyDown(KeyCode.S)) && (canRespond))
{ hasResponded = true; }
}
IEnumerator EnemyFadeIn(float timeToFade, float timeBetweenFades, float timeToWait) {
Debug.Log("An Enemy Is Fading In");
yield return new WaitForSeconds(timeToFade);
Debug.Log("An Enemy Has Appeared");
yield return ListenForInput(timeToFade, timeBetweenFades, timeToWait);
}
IEnumerator EnemyFadeOut(float timeToFade, float timeBetweenFades, float timeToWait) {
Debug.Log("An Enemy Is Fading Away");
yield return new WaitForSeconds(timeToFade);
Debug.Log("An Enemy Has Departed");
yield return new WaitForSeconds(timeBetweenFades);
yield return EnemyFadeIn(timeToFade, timeBetweenFades, timeToWait);
}
IEnumerator ListenForInput(float timeToFade, float timeBetweenFades, float timeToWait) {
canRespond = true;
Debug.Log("Press the 'S' Key to Destroy the Enemy!");
float startTime = Time.time;
while (Time.time < (startTime + timeToWait)) {
if (hasResponded) {
Debug.Log("The 'S' Key was Pressed!");
hasResponded = false;
canRespond = false;
yield return EnemyFadeOut(timeToFade, timeBetweenFades, timeToWait);
}
yield return new WaitForSeconds(0.25f);
}
Debug.Log("The 'S' Key was not Pressed!");
canRespond = false;
yield return ResetGame();
}
IEnumerator ResetGame() {
Debug.Log("Game is Performing a Reset");
yield return new WaitForSeconds(10);
Debug.Log("Game has Restarted. End of Coroutine!");
}
}
我创建了
EnemyFadeOut()
和
ListenForInput()
方法来配合
EnemyFadeIn()
和
ResetGame()
方法。这些是四个状态。行为流程如下:
首先,
Start()
Monobehaviour启动
EnemyFadeIn()
协程。
接下来,
EnemyFadeIn()
协程会在完全将敌人融入游戏世界后将控制权转移到
ListenForInput()
。
接下来,如果在给定的等待时间内按下“S”键,则
ListenForInput()
协程将将控制权转移到
EnemyFadeOut()
,否则将转移到
ResetGame()
。
如果控制权被传递给
EnemyFadeOut()
,则敌人将从世界中消失,然后控制权将传递给
EnemyFadeIn()
,循环将继续,直到玩家未能按下“S”键。
如果控制权被传递给
ResetGame()
,则表示玩家未能及时按下“S”键,游戏将执行所有必要的功能以重新开始。
控制台
Debug.Log()
和
yield return new WaitForSeconds()
用于模拟目的。由于iTween不是本地库,因此一些淡入/淡出代码必须被注释掉。