所以......我正在为这个Wave系统工作一个小游戏,我希望系统在产生另一个敌人之前等待一段特定的时间,所以我做了这件事:
void ExecuteWaveAction(WaveAction action)
{
int numberOfSpawns = spawnLocations.Length;
int currentSpawnToInstantiate = 0;
float timeLeftToSpawnEnemy = 0f;
for (int i = 0; i < action.quantityOfEnemysToSpawn; i++)
{
if (timeLeftToSpawnEnemy < action.spawnRate)
{
timeLeftToSpawnEnemy += Time.deltaTime;
i--;
}
else
{
GameObject.Instantiate (action.enemyToSpawn, spawnLocations [currentSpawnToInstantiate].position, Quaternion.identity);
currentSpawnToInstantiate++;
timeLeftToSpawnEnemy = 0f;
if (currentSpawnToInstantiate >= numberOfSpawns)
currentSpawnToInstantiate = 0;
}
}
}
如果你问自己WaveAction是什么:
public struct WaveAction
{
public int quantityOfEnemysToSpawn;
public float spawnRate;
public GameObject enemyToSpawn;
}
我不知道代码有什么问题,当我调试一切似乎没问题时,脚本实际上会在产生之前等待,但是当我正在播放脚本时会立即产生所有生物。
如果有人可以帮助我,我将非常感激,最后,如果我犯了任何拼写错误或英语错误,我很抱歉,我不是母语为英语的人
答案 0 :(得分:2)
我建议使用协程:
IEnumerator ExecuteWaveAction(WaveAction action) {
int currentSpawnToInstantiate = 0;
for (int i = 0; i < action.quantityOfEnemysToSpawn; i++)
{
// spawn object
GameObject.Instantiate (action.enemyToSpawn, spawnLocations [currentSpawnToInstantiate].position, Quaternion.identity);
currentSpawnToInstantiate++;
if (currentSpawnToInstantiate >= numberOfSpawns)
currentSpawnToInstantiate = 0;
// waits for 1 sec before continue. you can change the time value
yield return new WaitForSeconds(1);
}
}
答案 1 :(得分:1)
首先让我们看看Time.deltaTime
:
完成最后一帧所花费的时间(只读)。
使用此功能可以使您的游戏帧速率独立。
在Unity中,无论何时需要制定与时间相关的场景,您都必须使用协同例程,否则它完全取决于您的代码逻辑来衡量增量时间。
在一个简单的协同程序中,我们将逻辑包装在循环中,并且我们有一个yield语句,该值表示协程在每次传递后应该等待的时间(帧)。
Update
和FixedUpdate
方法是Unity内置协同程序,分别每Time.deltaTime
和Time.fixedDeltaTime
秒执行一次。
由于ExecuteWaveAction
必须使用增量时间,因此产卵的逻辑必须具有协程才能正常工作。
int numberOfSpawns = spawnLocations.Length;
int currentSpawnToInstantiate = 0;
float timeLeftToSpawnEnemy = 0f;
WaveAction action = set this in advance;
void Start()
{
action = ...
ExecuteWaveAction();
}
void ExecuteWaveAction()
{
numberOfSpawns = spawnLocations.Length;
currentSpawnToInstantiate = 0;
timeLeftToSpawnEnemy = 0f;
i = 0;
}
现在看一下循环逻辑如何与原始方法分离并放入协程:
int i = 0;
void Update()
{
//if spawning is active then continue...
if (i < action.quantityOfEnemysToSpawn)
{
if (timeLeftToSpawnEnemy < action.spawnRate)
{
timeLeftToSpawnEnemy += Time.deltaTime;
}
else
{
i++;
GameObject.Instantiate (action.enemyToSpawn, spawnLocations [currentSpawnToInstantiate].position, Quaternion.identity);
currentSpawnToInstantiate++;
timeLeftToSpawnEnemy = 0f;
if (currentSpawnToInstantiate >= numberOfSpawns)
currentSpawnToInstantiate = 0;
}
}
}
注意:
您可能想知道为什么我们不能在循环中使用Time.deltaTime?
答案是:因为Time.deltaTime表示一帧的时间长度(基本上等于同一Update
方法的每两次连续执行之间的延迟),但是一个简单的循环一次全部运行框架,因此Time.deltaTime只告诉我们一些其他延迟,我们的循环不会在它上面工作。
换句话说,Unity不会在循环内等待一个帧结束,但它会在执行每个协同程序后等待(等待时间=帧长度(即Time.deltaTime或Time.fixedDeltaTime或手动协程等待时间)。