Basically I have a turret that keeps on shooting white balls every frame which forms a long white line
I am guessing this is because update function updates something every frame which I don’t want so I have to create another fucntion ienumerator on csharp?
This is what I have so far
using UnityEngine;
using System.Collections;
public class bullet : MonoBehaviour {
public Transform spawnn;
public GameObject fire;
void Update () {
DoStuff ();
}
IEnumerator DoStuff()
{
yield return new WaitForSeconds(5.0f);
Instantiate(fire,spawn.transform.position , spawn.transform.rotation);
}
}
I’d put the yield after the instantiate to prevent a delay the player might think is lag, also don’t forget it’s “StartCoroutine(DoStuff());” if you want to start an enumerator with a yield return… otherwise I’d say you’re on the right track, set the waitforseconds to 2.0f and it should instantiate one every 2 seconds… theoretically. Unity CoRoutines can give some weird results
using UnityEngine;
using System.Collections;
public class bullet : MonoBehaviour {
public Transform Bulletspawn;
public GameObject Bulletfire;
void Update () {
StartCoroutine(DoStuff());
}
IEnumerator DoStuff()
{
yield return new WaitForSeconds(2.0f);
Instantiate(Bulletfire ,Bulletspawn.transform.position , Bulletspawn.transform.rotation);
}
}
So now I have this it waits 2 seconds, fires once but then it starts to fire continuously again? do you know why this is happening? How can I prevent this?
Your coroutine will only execute once, so if you are instantiating multiple bullets after the 2 second wait, you have another script somewhere which is doing it.
If you want your routine to loop,
IEnumerator DoStuff()
{
while(enabled)//Or some other condition that will be true until you don't need it
{
yield return new WaitForSeconds(2.0f);
Instantiate(Bulletfire ,Bulletspawn.transform.position , Bulletspawn.transform.rotation);
yield return null;
}
}
There’s got to be a better way to handle this than coroutines though, right? Maybe a clock reference to track time and instantiate every two seconds? I just don’t like a 2 second script pause, personal thing I guess?
Coroutines are a terrible way to solve this. You just record Time.time to a variable when you fire, then compare the current time to the variable and if more than two seconds have passed you fire and record the time.
Is simpler, and takes up the same amount of computation time, possibly less in some cases.
Sometimes, it’s better to just have the basics, bread and butter stuff. Only resort to coroutines where it actually would improve the code or be the right tool for the job.
You could have a thousand of those and it wouldn’t dent the profiler. I would use coroutines if I had to handle something more complicated though.
The reason this fires continuously is because every update you’re starting a new coroutine. So this has the same effect as Update() just being delayed by 2 seconds.
Your options are to use a boolean to check if a coroutine is already running, to use a timer in the update loop, use InvokeRepeating, or use async await.
Here’s a potential option:
using System.Collections;
using UnityEngine;
public class BulletSpawner : MonoBehaviour
{
public GameObject bulletPrefab;
public float fireRate = 2f;
public bool isFiring = true;
private void Start()
{
StartCoroutine(FireBullets());
}
private IEnumerator FireBullets()
{
while (isFiring)
{
FireBullet();
yield return new WaitForSeconds(fireRate);
}
}
private void FireBullet()
{
// Instantiate and set up the bullet here
GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}
You might be inclined to use Async
using System.Threading.Tasks;
using UnityEngine;
public class BulletSpawner : MonoBehaviour
{
public GameObject bulletPrefab;
public float fireRate = 2f;
public bool isFiring = true;
private async void Start()
{
while (isFiring )
{
FireBullet();
await Task.Delay((int)(fireRate * 1000)); // Convert fireRate to milliseconds
}
}
private void FireBullet()
{
// Instantiate and set up the bullet here
GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}
Timer is also a good option. Timer versus Async will have slightly different side effects. Time will stop firing immediately, while async will fire one last bullet then stop. It may not make a big impact to your game but something to consider.