Seinfeld
Seinfeld

Reputation: 433

(Unity) How to generate game objects every, E.G 5 seconds, randomly withing specific area ?

To be more precise, I'll post the picture.

enter image description here

The brownish cube should be an obstacle, while yellow should be the one that should be collected. However, how can I make those 2 prefabs randomly generated withing this red area, but all over the Z axis.

Since this plane is generated all over again when player reaches the half way, so it looks like an infinite terrain.

I do know roughly how it should look, but I'm not able to implement it, since I'm not so familiarized with the C# + Unity syntax.

If anyone can give at least demo of the possible code, that would be great.

Upvotes: 0

Views: 1615

Answers (2)

Everts
Everts

Reputation: 10701

you can use coroutine or you can use InvokeRepeating (Reusing creation method from Galandil):

[SerializeField] private float frequency = 2f; 
void Create()
{
    Vector3 brownSpawnPos = new Vector3 (Random.Range (0, width), 0, Random.Range (0, length));
    Vector3 yellowSpawnPos = new Vector3 (Random.Range (0, width), 0, Random.Range (0, length));
    Instantiate (brownPrefab, brownSpawnPos, Quaternion.identity, laneTransform);
    Instantiate (yellowPrefab, brownSpawnPos, Quaternion.identity, laneTransform);
}

void Start()
{
    InvokeRepeating("Create", frequency, frequency);
}

This will call MyMethod every two seconds. The first parameter indicates the first call, the second parameter indicates all next calls.

If you wish to change the frequency, for instance your player is getting faster, you can use Invoke:

[SerializeField] private float frequency = 2f; 
void CreateAndRestart()
{
    Create();
    // Frequency gets smaller
    frequency -= 0.1f;
    frequency = (frequency < 0.5f) ? 0.5f : frequency;
    // Launch a new counter
    Invoke("MyMethod", frequency);
}

void Start()
{
    Invoke("CreateAndRestart", frequency);
}

I made it so that it won't get below 0.5. You can obviously change that value but make sure it does not get below 0. Not sure if it breaks the Invoke when doing so but in any way, it won't make sense.

Upvotes: 1

Galandil
Galandil

Reputation: 4249

You have to use a Coroutine in order to spawn the objects at a fixed time interval.

IEnumerator SpawnCoroutine (float width, float length, Transform laneTransform)
    {
        WaitForSeconds waitTime = new WaitForSeconds(5);
        while (true) {
            Vector3 brownSpawnPos = new Vector3 (Random.Range (0, width), 0, Random.Range (0, length));
            Vector3 yellowSpawnPos = new Vector3 (Random.Range (0, width), 0, Random.Range (0, length));
            Instantiate (brownPrefab, brownSpawnPos, Quaternion.identity, laneTransform);
            Instantiate (yellowPrefab, brownSpawnPos, Quaternion.identity, laneTransform);
            yield return waitTime;
        }
    }

Width is X, Length is Z. In order for the code to start spawning indefinitely, you need to call it with the

StartCoroutine(SpawnCoroutine(xWidth, zLength, laneTransform));

If you need it to stop (since it's an infinite loop), you must keep a reference to the started coroutine and use that refernce for stopping the coroutine. So the start would look a bit different

var spawner = SpawnCoroutine(xWidth, zLength, laneTransform);
StartCoroutine(spawner);
StopCoroutine(spawner);

The spawned objects will be all child of the red area game object.

Upvotes: 2

Related Questions