c# - 使用 Yield 使函数等到某事为真 Unity C#
问题描述
我正在尝试使用 Yield,因此如果已达到最大数量,我的功能会等待在场景中生成更多敌人。但是现在函数在整个循环中跳过了所有这些。我从来没有使用过产量,所以也许我在阅读文档时理解错了它的作用。也可能有更好的方法来做到这一点。
while ( i < clonesASpawnear.Length)
{
if (j <= endList)
{
if (clonesASpawnear[i] == null)
{
if (sPCurrent == sPMax)
{
sPCurrent = 0;
}
yield return new WaitUntil(() => aliveEnemies < maxAmmoutOfEnemiesOnStage);
clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
clonesASpawnear[i].SetActive(true);
clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
aliveEnemies += 1;
clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
j++;
i++;
sPCurrent++;
}
}
else
{
j = startList;
}
}
}
按要求编辑:这是调用函数的更新
void Update()
{
if (pdh.playerIsDead == false && roundOver==false)
{
playerAliveTime += Time.deltaTime;
}
if (waveNumer <= 3 )
{
timeForNextSpawn -= Time.deltaTime;
if (timeForNextSpawn <= 0 && aliveEnemies == 0)
{
nextWaveTextUI.text = nextWaveText;
int waitT = (int)waitTimeForNewWave;
StartCoroutine(delayXSeconds(waitT));
timeForNextSpawn = waitTimeForNewWave;
auxWaveThisRound--;
waveNumer++;
spawnEnemies();
}
}
else
{
if(aliveEnemies == 0 && auxWaveThisRound <= 0)
{
clearedRoundTextUI.text = clearedRoundText;
roundOver = true;
StartCoroutine(waiterReset());
}
}
accuracy = successfulProjectiles / projectileFired;
}
以及上面代码所在的完整函数
IEnumerator spawnEnemies()
{
int percentForWave=0;
int percentForType=0;
int TotalEnemies = (int)enemySpawnsThisRound;
if (waveNumer == 1)
{
Debug.Log("Entro al wave 1");
percentForWave = 20;
percentForType = 20;
startList = 0;
}
if (waveNumer == 2)
{
Debug.Log("Entro al wave 2");
percentForWave = 70;
percentForType = 70;
startList = endList;
}
if (waveNumer == 3)
{
Debug.Log("Entro al wave 3");
percentForWave = 10;
percentForType = 10;
startList = endList;
}
int enemiesThisWave = Decimal.ToInt32(Math.Round(TotalEnemies * ((decimal)percentForWave / 100), 1));
int enemiesForType = Decimal.ToInt32(Math.Round(lenghtList * ((decimal)percentForType / 100), 1));
endList = enemiesForType + startList;
clonesASpawnear = new GameObject[enemiesThisWave];
int i = 0;
int j = startList;
while ( i < clonesASpawnear.Length)
{
if (j <= endList)
{
if (clonesASpawnear[i] == null)
{
if (sPCurrent == sPMax)
{
sPCurrent = 0;
}
yield return new WaitUntil(() => aliveEnemies < maxAmmoutOfEnemiesOnStage);
clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
clonesASpawnear[i].SetActive(true);//lo activo
clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
aliveEnemies += 1;
clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
j++;
i++;
sPCurrent++;
}
}
else
{
j = startList;
}
}
}
解决方案
不要使用 while 循环。相反,使用“更新()”。
void Update() {
if (aliveEnemies < maxAmmoutOfEnemiesOnStage && j <= endList)
{
if (clonesASpawnear[i] == null)
{
if (sPCurrent == sPMax)
{
sPCurrent = 0;
}
clonesASpawnear[i] = Instantiate(enemyTypeList[j], spawnPoints[sPCurrent].transform.position, Quaternion.Euler(0, 0, 0)) as GameObject;
clonesASpawnear[i].SetActive(true);
clonesASpawnear[i].GetComponent<EnemyMovement_DCH>().player = Target;
aliveEnemies += 1;
clonesASpawnear[i].GetComponent<EnemyDamageHandler_DCH>().SpawnerEnemies = this;
j++;
i++;
sPCurrent++;
}
}
else
{
j = startList;
}
}
这就是更新框架的想法。每一帧都会触发这里的逻辑。只有当敌人数量低于最大值时才会继续。这个方法必须进入一个扩展 MonoBehaviour 的类,否则它不会被调用。鉴于预期的逻辑,将其附加到一些主“游戏监控”游戏对象是有道理的,该游戏对象管理游戏的元数据以及胜利状态等。
编辑(更多内容后):这是一个问题“spawnEnemies();”。那是一个 IEnumerator,但你不使用“StartCoroutine(spawnEnemies())”。所以该方法实际上不会执行。不会有错误,但方法中不会发生任何事情。
推荐阅读
- sql - unpivot a sql(列到行)
- javascript - 使 JavaScript 画布背景透明
- unix - rsyslog 是否转发评论(#)?
- mysql - 为什么记录在 40 秒后到达
- excel - 有没有办法使用自动化将图片从内存加载到 excel 中?
- google-cloud-platform - GCP:无法连接到 Datalab
- python - 仅返回 x 变量方程之前的数字
- javascript - 如何在 react-native 中使用 node.js 和 Socket.io 实现实时聊天?
- c++ - C++ OpenCV卡尔曼滤波器构造函数错误
- grep - GREP:如何匹配正数或负数?