Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Unity_в_действии_Джозеф_Хокинг_Рус.pdf
Скачиваний:
83
Добавлен:
21.06.2022
Размер:
26.33 Mб
Скачать

11.2. Разработка общей игровой структуры      287

float progress = (float)numReady / numModules;

progressBar.value = progress; ¬ Обновляем ползунок данными о процессе загрузки.

}

private void OnManagersStarted() {

Managers.Mission.GoToNext(); ¬ После загрузки диспетчеров загружаем следующую сцену.

}

}

Теперь свяжите объект Slider с ячейкой на панели Inspector. Остался всего один подготовительный шаг. Нужно добавить две сцены в список Build Settings. Процедура создания приложения рассматривается в следующей главе, а пока просто выберите в меню File команду Build Settings для просмотра и корректировки списка сцен. Щелкните на кнопке Add Current, чтобы добавить в список текущую сцену (загрузите обе сцены и проделайте эту операцию для каждой из них).

ПРИМЕЧАНИЕ  Добавление в список Build Settings необходимо для загрузки сцен. Без этого Unity не узнает, какие из сцен доступны. В главе 5 нам эта операция не требовалась, так как мы не переходили от одной сцены к другой, а только перезагружали текущую сцену.

Теперь можно загрузить игру, щелкнув на кнопке Play в сцене Startup. Объект Game Managers будет использоваться в обеих сценах.

ВНИМАНИЕ  Так как диспетчеры загружаются в сцене Startup, именно отсюда все время нужно запускать игру. Можно запомнить, что перед щелчком на кнопке Play всегда требуется переходить к этой сцене, а можно воспользоваться сценарием http://wiki.unity3d.com/index.php/ SceneAutoLoader, который будет автоматически перебрасывать вас в нужное состояние после щелчка на кнопке Play.

Это структурное изменение отвечает за совместное использование диспетчеров различными сценами, но на уровнях пока отсутствуют индикаторы успешного прохождения уровней и гибели персонажа.

11.2.2. Завершение уровня

Для завершения уровня в сцену нужно поместить объект, который в ответ на касание персонажа будет информировать диспетчер MissionManager об успешном достижении цели. Для этого нам потребуется пользовательский интерфейс, реагирующий на сообщение о завершении уровня, поэтому добавьте в сценарий GameEvent содержимое следующего листинга.

Листинг 11.19. Код завершения уровня, добавляемый в сценарий GameEvent

public static class GameEvent {

public const string HEALTH_UPDATED = "HEALTH_UPDATED"; public const string LEVEL_COMPLETE = "LEVEL_COMPLETE";

}

Теперь добавьте в сценарий MissionManager новый метод для слежения за целями миссий и рассылки новых сообщений о событиях (см. следующий листинг).

288      Глава 11. Объединение фрагментов в готовую игру

Листинг 11.20. Метод слежения за целями в сценарии MissionManager

...

public void ReachObjective() {

// здесь может быть код обработки нескольких целей

Messenger.Broadcast(GameEvent.LEVEL_COMPLETE);

}

...

Отредактируйте сценарий UIController, как показано в следующем листинге, чтобы он начал реагировать на данное событие.

Листинг 11.21. Новый подписчик на событие в сценарии UIController

...

[SerializeField] private Text levelEnding;

...

void Awake() {

Messenger.AddListener(GameEvent.HEALTH_UPDATED, OnHealthUpdated); Messenger.AddListener(GameEvent.LEVEL_COMPLETE, OnLevelComplete);

}

void OnDestroy() {

Messenger.RemoveListener(GameEvent.HEALTH_UPDATED, OnHealthUpdated); Messenger.RemoveListener(GameEvent.LEVEL_COMPLETE, OnLevelComplete);

}

...

void Start() { OnHealthUpdated();

levelEnding.gameObject.SetActive(false);

popup.gameObject.SetActive(false);

}

...

private void OnLevelComplete() { StartCoroutine(CompleteLevel());

}

private IEnumerator CompleteLevel() { levelEnding.gameObject.SetActive(true); levelEnding.text = "Level Complete!";

yield return new WaitForSeconds(2); ¬

Managers.Mission.GoToNext();

}

...

Отображаем сообщение в течение двух секунд, а потом переходим на следующий уровень.

Обратите внимание, что в этом листинге есть ссылка на текстовую метку. Откройте сцену Level1 и создайте новый текстовый объект UI. Эта метка будет содержать сообщение о завершении уровня, появляющееся в центре экрана. Присвойте параметру Width этого текста значение 240, параметру Height — значение 60, для выравнивания по горизонтали и вертикали выберите вариант Center, а параметр Font Size сделайте равным 22. В текстовое поле введите слова Level Complete! и свяжите текстовый объект со ссылкой levelEnding в сценарии UIController.

11.2. Разработка общей игровой структуры      289

Теперь осталось создать объект, прикосновение к которому позволит завершить уровень. Пример такого объекта показан на рис. 11.8. Он напоминает доступные для сбора элементы инвентаря: потребуется материал и сценарий, а затем мы превратим этот объект в шаблон экземпляра.

Ц

К а а а а , а а а

Рис. 11.8. Целевой объект, к которому должен прикоснуться персонаж для завершения уровня

Создайте куб и введите в поля Position значения 18, 1, 0. Установите флажок Is Trigger в свитке Box Collider, отключите возможность отбрасывать и получать тени в свитке Mesh Renderer и поместите объект в слой Ignore Raycast. Создайте новый материал с именем objective; сделайте его ярко-зеленым и выберите вариант раскраски Unlit Color для получения равномерного яркого представления.

Теперь создайте сценарий ObjectiveTrigger (показанный в следующем листинге) и свяжите его с целевым объектом.

Листинг 11.22. Код сценария ObjectiveTrigger для применения к целевым объектам

using UnityEngine;

using System.Collections;

public class ObjectiveTrigger : MonoBehaviour { void OnTriggerEnter(Collider other) {

Managers.Mission.ReachObjective(); ¬ Вызываем новый целевой метод в сценарии MissionManager.

}

}

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

Теперь нужно создать сообщение, появляющееся в момент смерти персонажа.

11.2.3. Проигрыш уровня

Условием проигрыша является полная утрата здоровья персонажем (из-за успешных атак врагов). Первым делом добавьте еще одну строку в сценарий GameEvent:

public const string LEVEL_FAILED = "LEVEL_FAILED";

290      Глава 11. Объединение фрагментов в готовую игру

Далее отредактируйте сценарий PlayerManager, чтобы падение уровня здоровья до нуля сопровождалось рассылкой сообщения, как показано в следующем листинге.

Листинг 11.23. Рассылка сообщения о проигрыше из сценария PlayerManager

...

public void Startup(NetworkService service) { Debug.Log("Player manager starting...");

_network = service;

UpdateData(50, 100); ¬ Вызываем метод обновления вместо того, чтобы задавать переменные напрямую.

status = ManagerStatus.Started;

}

public void UpdateData(int health, int maxHealth) { this.health = health;

this.maxHealth = maxHealth;

}

public void ChangeHealth(int value) { health += value;

if (health > maxHealth) { health = maxHealth;

}else if (health < 0) { health = 0;

}

if (health == 0) { Messenger.Broadcast(GameEvent.LEVEL_FAILED);

}

Messenger.Broadcast(GameEvent.HEALTH_UPDATED);

}

public void Respawn() { ¬ Возвращаем игрока в исходное состояние.

UpdateData(50, 100);

}

...

Для возвращения к началу уровня добавим небольшой метод в сценарий MissionMana­ ger (см. следующий листинг).

Листинг 11.24. Сценарий MissionManager, который может начинать текущий уровень сначала

...

public void RestartCurrent() { string name = "Level" + curLevel; Debug.Log("Loading " + name); Application.LoadLevel(name);

}

...

После этого добавьте еще одного подписчика на событие в сценарий UIController, как показано в следующем листинге.