Создание асинхронного игрового объекта Unity3D

Я делаю свой первый проект в Unity3D прямо сейчас. Это 2D игра. Это своего рода runner, но с возможностью для игрока вернуться назад на некоторое расстояние. Чтобы реализовать эту функциональность на данный момент, я делаю что-то вроде этого:

  • Создание двух экранов с контентом (первый для просмотра в начале игры, второй для отображения после того, как игрок превысит первый экран)
  • Когда игрок переходит на следующий экран, я вычисляю текущую позицию и размер экрана, чтобы создать новый после него (так что это 2 с самого начала, и когда игрок переходит на второй, создается третий и так далее)

Когда я тестировал его на своем ПК, все было в порядке, но по какой-то причине, когда создается следующий экран, мой телефон зависает примерно на секунду, теперь как выглядит код:

В методе Start() скрипта я инициализирую две сцены:

    Scene scene = new Scene ();
    scene.setSceneBounds (screenBounds);
    scene.createBackground (cameraOffsetOnStart, sceneSize);
    scene.createContent ();

    sceneNumber++;
    currentScenePosition = sceneSize * sceneNumber;
    Vector2 nextScenePosition = new Vector2 (cameraOffsetOnStart.x + currentScenePosition.x, cameraOffsetOnStart.y);

    Scene scene2 = new Scene ();
    screenBounds.min = new Vector2(min.x + currentScenePosition.x, min.y);
    screenBounds.max = new Vector2(max.x + currentScenePosition.x, max.y);
    scene2.setSceneBounds (screenBounds);
    scene2.createBackground (nextScenePosition, sceneSize);
    scene2.createContent ();

И затем в Update() я проверяю, превышает ли игрок текущую сцену и создаю новую:

void Update () {
    if (player.transform.position.x - playerOffset > sceneNumber * (max.x - min.x)) {
        Debug.Log("current scene is : " + (++sceneNumber));
        currentScenePosition = sceneSize * sceneNumber;
        Vector2 nextScenePosition = new Vector2 (cameraOffsetOnStart.x + currentScenePosition.x, cameraOffsetOnStart.y);
        Scene scene = new Scene();
        screenBounds.min = new Vector2(min.x + currentScenePosition.x, min.y);
        screenBounds.max = new Vector2(max.x + currentScenePosition.x, max.y);
        scene.setSceneBounds (screenBounds);
        scene.createBackground(nextScenePosition, sceneSize);
        scene.createWebs();
        sceneManager.Scenes.Add(scene);
    }
}

И код для создания контента:

public void createBackground(Vector2 position, Vector2 size) {
    background = new Background (position, size);
}

public void createContent() {
    Vector2[] positions = Utilities.generateRandomPositions(5, sceneBounds, 4f);

    for (int i = 0; i < positions.Length; i++) {
        Web web = ScriptableObject.CreateInstance<Web>();
        web.init(positions[i]);
    }
}

Проблема отставания возникает из-за метода createContent. Код для init :

    public void init(Vector2 position) {
        if (position != Vector2.zero) {
            obj = Instantiate (Resources.Load ("Textures/web", typeof(GameObject)), position, Quaternion.identity) as GameObject;
        }
    }

Очевидно, что такое поведение вызывает метод Instantiate, вызывающий 5 раз подряд для 5 объектов.

Подробнее о "Текстурах/сети", если нужно: Это префаб с круговым коллайдером и твердым телом, настроенным на кинематику.

Вопросы. Почему отстают только 5 элементов? Я неправильно использую Instantiate? Как я могу сделать это быстрее? Есть ли способ назвать это асинхронным?


person Nik Myers    schedule 27.06.2016    source источник
comment
Насколько я помню, операция Resources.Load в сочетании с Instantiate заняла много времени. Если это возможно, попробуйте, например, загрузить GameObject в Stat и просто создать экземпляр этого объекта, когда вам нужно.   -  person Paweł Marecki    schedule 27.06.2016
comment
@PawełMarecki, так что, по сути, ты говоришь, что я загружаю один и тот же ресурс снова и снова? О, это плохо, я попробую сделать это как доступный GameObject, инициализированный один раз, минутку   -  person Nik Myers    schedule 27.06.2016
comment
@PawełMarecki, вау, большое спасибо, вы действительно решили мою проблему, я не осознавал, что загружаю один и тот же ресурс несколько раз =(   -  person Nik Myers    schedule 27.06.2016
comment
Отлично :D Рад помочь вам. Оставляю ответ в клановой ветке.   -  person Paweł Marecki    schedule 27.06.2016
comment
@PawełMarecki, хорошо, спасибо   -  person Nik Myers    schedule 27.06.2016


Ответы (1)


Как обсуждалось в комментариях.

В соответствии:

obj = Instantiate (Resources.Load ("Textures/web", typeof(GameObject)), position, Quaternion.identity) as GameObject;

Вы загружаете ресурсы из памяти устройств каждый раз, когда вызываете этот код. Просто сохраните GameObject в какой-нибудь переменной, например, в методе Start().

person Paweł Marecki    schedule 27.06.2016