Я делаю свой первый проект в 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
? Как я могу сделать это быстрее? Есть ли способ назвать это асинхронным?
Resources.Load
в сочетании сInstantiate
заняла много времени. Если это возможно, попробуйте, например, загрузитьGameObject
вStat
и просто создать экземпляр этого объекта, когда вам нужно. - person Paweł Marecki   schedule 27.06.2016