Loading...
krisitown avatar krisitown 45 Точки

Проблем с WaitForSeconds метода

Опитвам се да не викам метода SpawnEnemy() всеки frame. Използвам WaitForSeconds метода за да създам delay. Но поради някаква причина този код не работи, а SpawnEnemy() се вика всеки frame. Ето кода:

 

	void Update () {	
		SpawnEnemy();
		StartCoroutine(WaitTime());
		SpawnEnemy();
	}

	IEnumerator WaitTime(float seconds)
	{
		yield return new WaitForSeconds(seconds);
	}

Просто не искам да spawn-вам 60 пъти в секунда, а 1-2 пъти на секунда.

Тагове:
1
Unity 3D
nightwallker avatar nightwallker 1 Точки

using UnityEngine;
using System.Collections;

public class EnemySpawn : MonoBehaviour {


    public GameObject enemy;
    public float spawnTime = 3f;
    public Transform spawnPoint;
    void Start()
    {
        // Call the Spawn function after a delay of the spawnTime and then continue to call after the same amount of time.
        InvokeRepeating("Spawn", spawnTime, spawnTime);
    }
    void Spawn()
    {
 

        // Create an instance of the enemy prefab at the  selected spawn point's position and rotation.
        Instantiate(enemy, spawnPoint.position, spawnPoint.rotation);
    }

Това би трябвало да реши проблема ти.

0
24/02/2016 00:18:51
keller avatar keller 45 Точки

Не го използваш правилно. Ти пускаш Coroutine което е се изпълнява на отделен тред. Пускането на карутината не спира екзекуцията на другия метод - Coroutine-ата работи отделно.

Също, това го правиш във ъпдейт метода - това означава че всеки кадър ще правиш по още една гадина. Тука имаш два варианта. Единия е ъпдейт, другия карутин. Ето код:

class OptionOne{

	float Timer = 0;
	float SpawnRate = 1.5f;

	void Update()
	{

		Timer += Time.deltaTime;
		if(Timer > SpawnRate)
		{
			Timer = 0;
			SpawnEnemy();
		}
	}
}

class OptionTwo{
	float SpawnRate = 1.5f

	void Start()
	{
		StartCoroutine(Spawner(SpawnRate));
	}

	IEnumerator Spawner(float interval)
	{
		while(true)
		{		
			SpawnEnemy();
			yield return new WaitForSeconds(interval);
		}
	}
}

 

Също можеш да използваш InvokeRepeating, Но до колкото знам не е най-добрата практика защото ползва Reflection.

1
25/02/2016 16:19:06
gvanastasov avatar gvanastasov 52 Точки

Можеш и с едно флагче да си оправиш кода (като Option 3 от предложенията на keller):

http://pastebin.com/PHb8vmg0

, но мисля че чисто логичеки неговите са по-правилни, пак зависи от случая де

0
12/03/2016 22:21:23
HPetrov avatar HPetrov 822 Точки

Варианта на keller първия с Time.deltaTime е най-добрия от всички като искаш просто през определен период да spawn-ваш нови enemy-та. Можеш разбира се да го въртиш по някакъв начин и в coroutine но като можеш да избягваш изобщо да пускаш coroutine няма за какво да го правиш. Обикновено coroutines се ползват за други неща когато например искаш някакъв по-добър контрол върху нещо което правиш. Можеш да пробваш да правиш сметките и в FixedUpdate() като там ще ползваш Time.fixedDeltaTime. Ще се извиква 1 идея по-рядко от Update() но пък е по-точен откъм време.

0
gvanastasov avatar gvanastasov 52 Точки

не съм напълно сългасен - точно ползването на корутина е по-добрия начин тъй като ти дава страшно лесен начин за контрол върху start, stop на някакъв алгоритъм. Да не говорим примерно за ситуацията когато имаш 200 spawn места, вместа да имаш 200 чудесии да въртят в Update, можеш да имаш 1 коротуна (в някой там manager), която да върти и да казва на всички spawn инстанции да спанват (така де пак зависи от ситуацията), но както споменах контрол и оптимизация :)

0
HPetrov avatar HPetrov 822 Точки

О, в Update() можеш да имаш достатъчно добър контрол. Плюс това чисто като перформънс Update() е доста по-лек от цял Coroutine. В повечето ситуации вече ще имаш нещо случващо се в Update() и добавянето му на 1 парче код, което да spawn-ва разни неща на определено период от време не е никаква драма. Coroutine-а наистина дава страшно голяма гъвкавост и контрол над нещата, но да седиш и да циклиш в 1 coroutine не е добра практика, нито добра идея :) Trust me on this ;)

0
gvanastasov avatar gvanastasov 52 Точки

И искаш да кажеш, че 60 примерно Update call-a, е по-добре от 1 call със изчакване? Ами в ситуацията, която ти описах?

Нямам време да ги замеря лично аз, за това намерих в нето, и то от всеизвестния Eric5h5 - и той се е прозинесал по темата вярвам му! :D

5000 objects with a simple loop behaviour

InvokeRepeating: That normally takes .03 milliseconds per frame, with spikes of 2.38 ms every second (when all 5000 functions run).

WaitForSeconds: also takes .03 ms per frame, but the spikes are 4.03 ms every second

Update(): 0.93 ms, 100fps -> 93.0ms

Аз поне виждам огромна разлика. Дано не си ме разбрал погрешно. Напълно съм наясно, че контрол имаш и във Update(), но вярвай ми, работил съм по игри за таблети на по 6-7години, и там брояхме всеки един един ред в Update-а ;)

edit: референция към темата - http://forum.unity3d.com/threads/coroutines-vs-update.67856/

0
25/03/2016 11:04:11
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.