1
votes

I am creating a game, with-in the game there's 7 GameObject Prefabs, each one Instantiate it's on level, I am now creating the main script that will instantiate each GameObject Prefab, now what I want to do, is so create each 80f "seconds" to instantiate a new GameObject Prefab, and destroy the last one, for example, in 0f seconds since Level Started, Instantiate (Random) GameObject Prefab, and in 80f seconds destroy the one I created in 0f seconds, and Instantiate a new one, and so on.

This is the script that I have right now, it doesn't work, it does Instantiate new gameobject, but do not destroy the last one I created. I hope you can help me / give me an idea how to solve this problem NOTE I tried using Stack, but when I destroy Prefab from the stack, it destroyes the prefab it self, and it's not recoverable.my script:

    TimeSinceLevelStarted = Time.timeSinceLevelLoad;
    if (Mathf.Clamp(TimeSinceLevelStarted - TimeToLoadNext, -2f, 2f) == TimeSinceLevelStarted - TimeToLoadNext
        && LoadedFirstLevel == false)
    {
        GameObject go = LevelsPrefabs[Random.Range(0, LevelsPrefabs.Length)];
        FirstLevel(go);
        LoadedFirstLevel = false;
        Debug.Log("Instantiated Prefab2");
    }
    }

private void FirstLevel(GameObject go)
{
    if (LoadedFirstLevel == false)
    {
        Instantiate(go, new Vector3(0, 0, 0), Quaternion.identity);
        goStack.Push(go);
        Debug.Log("Instantiated Prefab1");
        TimeToLoadNext += 50f;
        LoadedFirstLevel = false;
        if (TimeToLoadNext >= 30f) {
            Destroy(go);
        }
    }
}
1
Use coroutines.Draco18s no longer trusts SE
If your issue is only destroying the object after a delay: Destroy has an overload taking a delay in seconds like Destroy(obj, 80.0f);derHugo

1 Answers

3
votes

Repeating events are best done with Coroutines. Also Unity tells us to avoid instantiating and destroying GameObjects when the game runs (since its "slow") - especially if they might get reused.

So a quick and dirty implementation of your desired behaviour should be the following. If you want to make sure that an object doesnt get actived twice in succession, you cant take the straight forward random approach, but youll need to shuffle the array and spawn it in the new order. There are plenty of examples for shuffling an array available. The below should be easily adaptable with a bit of tinkering on your side ;)

public class RandomSpawner : MonoBehaviour {

    //i learned there should always be an option to break out of a loop
    public bool exitCoroutine = false;

    public GameObject[] prefabs;
    public float waitTime = 80.0f;

    WaitForSeconds waitObject;
    GameObject[] gameObjects;
    int currentlyActive = 0;

    void Start() {

        waitObject = new WaitForSeconds(waitTime);

        gameObjects = new GameObject[prefabs.Length];

        for (int i = 0; i < prefabs.Length; i++) {
            gameObjects[i] = Instantiate(prefabs[i]);
            gameObjects[i].SetActive(false);
        }

        StartCoroutine(SpawnRandomObject());
    }

    void ActivateRandom() {
        int nextActive = Random.Range(0, gameObjects.Length);
        gameObjects[currentlyActive].SetActive(false);
        gameObjects[nextActive].SetActive(true);
        currentlyActive = nextActive;
    }

    IEnumerator SpawnRandomObject() {

        while (!exitCoroutine) {
            ActivateRandom();

            yield return waitObject;
        }
    }
}

https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html https://docs.unity3d.com/ScriptReference/WaitForSeconds.html