Как уничтожить GameObject и создать новый через некоторое время

Я создаю игру, в которой есть 7 префабов GameObject, каждый из которых создает экземпляр на уровне, сейчас я создаю основной скрипт, который будет создавать экземпляры каждого префаба GameObject, теперь то, что я хочу сделать, это создать каждый 80f " секунд ", чтобы создать новый префаб GameObject, и уничтожить последний, например, через 0f секунд с момента запуска уровня, создать экземпляр (случайный) GameObject Prefab, и за 80f секунд уничтожить тот, который я создал за 0f секунд, и создать новый экземпляр , и так далее.

Это сценарий, который у меня есть прямо сейчас, он не работает, он создает экземпляр нового игрового объекта, но не уничтожает последний созданный мной. Я надеюсь, что вы можете помочь мне / подскажите, как решить эту проблему. ПРИМЕЧАНИЕ Я пробовал использовать Stack, но когда я уничтожаю Prefab из стека, он уничтожает сам сборный файл, и его невозможно восстановить. мой сценарий:

    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);
        }
    }
}

person Jhony Sitbon    schedule 28.10.2018    source источник
comment
Используйте сопрограммы.   -  person Draco18s no longer trusts SE    schedule 29.10.2018
comment
Если ваша проблема заключается в уничтожении объекта только после задержки: Destroy имеет перегрузку с задержкой в ​​несколько секунд, например Destroy(obj, 80.0f);   -  person derHugo    schedule 29.10.2018


Ответы (1)


Повторяющиеся события лучше всего выполнять с помощью сопрограмм. Также Unity говорит нам избегать создания и уничтожения GameObjects во время работы игры (поскольку она «медленная») - особенно если они могут быть использованы повторно.

Итак, быстрая и грязная реализация вашего желаемого поведения должна быть следующей. Если вы хотите убедиться, что объект не активируется дважды подряд, вы не можете использовать прямой случайный подход, но вам нужно перетасовать массив и создать его в новом порядке. Существует множество примеров перетасовки массива. Приведенное ниже должно быть легко адаптировано с вашей стороны;)

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

person yes    schedule 29.10.2018
comment
Большое вам спасибо за вашу помощь, вы настоящий спасатель жизни! Тем не менее, у меня есть 1 проблема, когда gameObject создается, затем исчезает, когда он появляется снова, он не появляется из верхней части экрана, он остается в том же положении, что может привести к проигрышу игрока, не сделав ничего плохого, как я могу это исправить? :) - person Jhony Sitbon; 29.10.2018
comment
@JhonySitbon Я не знаю, что делают ваши GameObjects, но у меня есть предположение, что может решить вашу проблему. У GameObjects есть две функции OnEnable и OnDisable, которые вы можете перегрузить. Вероятно, вам придется использовать их для сброса положения, когда они отключены (или включены, это действительно не имеет значения). Если вам нужна дополнительная помощь, чем две ссылки ниже, не стесняйтесь открывать новый вопрос (и не забудьте дать хорошее описание и образец кода того, что вы пробовали) docs.unity3d.com/ScriptReference/MonoBehaviour.OnEnable.html и docs.unity3d.com/ScriptReference/MonoBehaviour.OnDisable.html - person yes; 29.10.2018