Фоновая загрузка сцены / уровня

В Unity, при вызове функции LoadLevel, изображение на экране «замирает», пока загружается следующая сцена. И в принципе, если карты в игре «легкие», то всё это происходит быстро, в целом не критично. Особенно, если использовать переход в затемнение и обратно, между сценами. Но если, уровни достаточно сложные, то процесс загрузки может занять некоторое время. Поэтому в играх делают фоновую загрузку, для таких случаев, например, загрузка на фоне картинки или видео. Прогресс бар загрузки, всё реже наблюдается в современных играх, чаще просто значок загрузки и какая-нибудь информация. Именно это мы и сделаем сегодня.


В папке Scripts вашего проекта создайте с# скрипт под именем, например, GameMenedjer. И в нем зашипим одну переменную, которой мы будем передавать имя следующей сцены для загрузки:

public static string levelName;

Теперь надо на уровень добавить триггер, для перехода на другую карту, Создаем обычный куб, на коллайдере ставим галочку Is Trigger. Сам куб обзываем именем GameFinish. Разместите его там, где должен заканчиваться уровень и настройте размеры. Выключаем Mesh Renderer. На куб вешаем скрипт с таким-же названием:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class GameFinish : MonoBehaviour {

	public string level;

	void OnTriggerEnter(Collider coll)
	{
		if(coll.transform.CompareTag("Player"))
		{
			GameMenedjer.levelName = level;
			SceneManager.LoadScene("Loading");
		}
	}
}

Не забываем указать имя сцены для загрузки в переменной - level.

Продолжим, создаем новую сцену и сразу сохраняем ее под именем Loading. Добавляем GameObject -> UI -> Image и переименуем в BG, это будет фон, устанавливаем цвет картинки в черный и параметры позиции так, как показана на скриншоте ниже:

Фоновая загрузка сцены / уровня

Фон готов!

Добавим еще одно изображение под именем Loading, в качестве источника, возьмем какой-нибудь значок загрузки, например вот такой:


Сделаем анимацию, выделяем картинку и переходим на вкладку Animation, затем, Add Property -> Rect Transform -> Rotation. И делаем ключевые кадры, от 0 до 360 по оси Z:


Выключаем объект, чтобы не мешался и устанавливаем его в правый нижний угол, а также ставим соответствующий пресет якоря:


С этим всё.

Добавляем GameObject -> UI -> Text под именем LoadingComplete, этот текст будет появляться после того, когда уровень будет загружен, разместите его там-же, где и значок загрузки.

Создаем пустой объект Ctrl+Shift+N с любым именем, а на него вешаем скрипт GameLoading:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class GameLoading : MonoBehaviour {

	public KeyCode _keyCode = KeyCode.Space;
	public GameObject loadingInfo, loadingIcon;
	private AsyncOperation async;

	IEnumerator Start() 
	{
		async = SceneManager.LoadSceneAsync(GameMenedjer.levelName);
		loadingIcon.SetActive(true);
		loadingInfo.SetActive(false);
		yield return true;
		async.allowSceneActivation = false;
		loadingIcon.SetActive(false);
		loadingInfo.SetActive(true);
	}

	void Update ()
	{
		if(Input.GetKeyDown(_keyCode)) async.allowSceneActivation = true;
	}
}

В переменной _keyCode можно выбрать, какую клавишу наживать, по умолчанию это - "Пробел".

loadingInfo - текст перед стартом игры, например; "Нажмите 'пробел', чтобы начать игру."
loadingIcon - иконка загрузки, которая будет показываться пока сцена загружается.

Комментариев 10

Офлайн
sniper1rdr 30 января 2019
Всем привет, прошу подсказать как реализовать нужную мне функцию, а то осталось до реализации совсем чуть чуть и не могу доделать

У меня есть кнопка SaveScene - которая сохраняет информацию о последнем уровне и и выводит меня в меню.

Кнопка CointinueGame загружает последний уровень в котором я был, беря информацию из SaveScene.

И есть кнопка LoadScene - в данный момент у неё стоит код который производит загрузку уровня в фонне. но он производит загрузку только если я напишу название уровня

Так вот я хочу объединить LoadScene и ContinueGame, что бы при нажатии продолжить игру загружался последний уровень в фоне из SaveScene то есть понимал "lastLevel" из PlayerPrefs

Скрипт фона брал этот

Офлайн
Light 23 марта 2017
DeDos, смотреть надо проект, если хочешь кинь ссылку на архив проекта в ЛС, посмотрим.
Офлайн
DeDos 23 марта 2017
Light,
А чем это может быть вызвано?
Офлайн
Light 23 марта 2017
DeDos, проверил на версии 5.5.2 проблем не обнаружено.
Офлайн
DeDos 22 марта 2017
При использовании этого скрипта у меня идет "вечная" загрузка уровня как это исправить?
Офлайн
Sershum 22 февраля 2017
Есть фишка по асинхронной загрузке(не моя)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class TestAsyncLoad : MonoBehaviour {

#region Public Variables
[Header("Graphics")]
public Image progressIndicator;
#endregion

#region Private Variables
#endregion

#region Local Variables
bool startLoad;
AsyncOperation sync;
#endregion

#region Built In Functions
void Start() {
// When we load the "Load Level" scene, automatically start the load process | Optionally we'd call it externally and supply a scene name to the "levelToLoad" field
BeginLoadOperation("Test3");
}

void Update() {
if (startLoad) {
Debug.Log("Load Progress: " + sync.progress);
progressIndicator.fillAmount = sync.progress;

if (sync.progress >= 0.9f) {
progressIndicator.fillAmount = 1.0f;
LoadLevel();
startLoad = false;
}
}
}
#endregion

#region Main Functions
void LoadLevel() {
sync.allowSceneActivation = true;
}
#endregion

#region Utility Functions
public void BeginLoadOperation(string levelToLoad) {
if (!string.IsNullOrEmpty(levelToLoad)) {
sync = SceneManager.LoadSceneAsync(levelToLoad);
sync.allowSceneActivation = false;
progressIndicator.fillAmount = 0;
startLoad = true;
}
}
#endregion
}

Хотелось бы знать мнение, камменты радовали бы))))))))
Офлайн
Light 3 февраля 2017
Atanashi, убедись чтобы в скрипте GameMenedjer была переменная:

public static string levelName;

Далее, проверь чтобы твои классы/скрипты не назывались так же, как классы Юнити.
Офлайн
Atanashi 2 февраля 2017
Здравствуйте. В версии Unity 5.5.0f3 появляются ошибки:
1. Assets/Portal of time/Resurse/Load Level/GameFinish.cs(13,17): error CS0117: `GameMenedjer' does not contain a definition for `levelName'
2. Assets/Portal of time/Resurse/Load Level/GameFinish.cs(14,17): error CS0117: `SceneManager' does not contain a definition for `LoadScene'
3. Assets/Portal of time/Resurse/Load Level/GameLoading.cs(13,24): error CS0117: `SceneManager' does not contain a definition for `LoadSceneAsync'
Офлайн
vasakot 28 декабря 2016
Спасибо большое,отличный сайт!!!
Офлайн
fersen 7 июля 2016
UnityEngine.SceneManagement появился в только в Unity 5.3,
Что же Вы сразу не предупредили, я бы пол вечера не убил на это дело.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика