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

232

    Глава 9. Подключение игры к Интернету

 

SetOvercast(Managers.Weather.cloudValue); ¬ Используем значение облачности

}

из сценария WeatherManager.

private void SetOvercast(float value) { sky.SetFloat("_Blend", value);

sun.intensity = _fullIntensity - (_fullIntensity * value);

}

}

Обратите внимание, что изменения сводятся не только к дополнениям; удалены несколько фрагментов тестового кода, а именно, мы удалили локальное значение облачности, увеличивавшееся в каждом кадре; оно нам больше не требуется, так как мы будем пользоваться значением из сценария WeatherManager.

Подписчики добавляются и удаляются в методах Awake() и OnDestroy() — это методы класса MonoBehaviour, вызываемые, когда объект активируется или удаляется. Каждый такой подписчик является частью системы рассылки сообщений. При получении сообщения он вызывает метод OnWeatherUpdated(), получающий значение облачности из сценария WeatherManager и, в свою очередь, вызывающий метод SetOvercast(), использующий это значение. В результате вид сцены контролируется скачанными из Интернета метеорологическими данными.

Выполните воспроизведение сцены и убедитесь, что небо обновляется в соответствии с информацией об облачности из прогноза погоды. Скорее всего, вы увидите, что запрос погоды занимает некоторое время; в настоящей игре до завершения загрузки неба имело бы смысл спрятать сцену за экраном загрузки.

ДРУГИЕ СПОСОБЫ ПЕРЕДАЧИ ДАННЫХ ПО СЕТИ В ИГРАХ

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

Существуют различные технологии взаимодействия, а также приемы, позволяющие скомпенсировать запаздывание. К примеру, в Unity применяется сетевая библиотека RakNet в системе удаленного вызова процедур (Remote Procedure Call, RPC).

Передовые технологии для создания сетевых игр — сложная тема, рассмотрение которой выходит за рамки темы данной книги. Вы можете самостоятельно заняться ее изучением, начав со страницы http://docs.unity3d.com/ru/current/Manual/NetworkReferenceGuide.html.

Теперь, когда вы знаете, как получить из Интернета числовые и строковые данные, давайте рассмотрим способы работы с изображениями.

9.3. Добавление рекламного щита

Ответы от веб-сервиса почти всегда представляют собой текстовые строки в формате XML или JSON, но по сети передается и множество других данных. Кроме текстовой информации чаще всего запрашиваются изображения. Объект WWW в Unity применяется в числе прочего и для их скачивания.

Способ решения этой задачи вы изучите на примере создания рекламного щита, на котором отображается скачанное из Интернета изображение. Создаваемый код будет

Этот обратный вызов вместо строки принимает объекты типа Texture2D.

9.3. Добавление рекламного щита      233

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

9.3.1. Загрузка изображений из Интернета

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

Рис. 9.5. Озеро Морейн в национальном парке Банф, Канада

Структура кода, предназначенного для скачивания данных и графики, практически одинакова. За загрузку изображений будет отвечать помещенный в отдельный модуль очередной диспетчер (он называется ImagesManager). Напомню, что за подключение к Интернету и отправку HTTP-запросов отвечает сценарий NetworkService, к которому и будет обращаться наш новый диспетчер. Первым делом отредактируем код сценария NetworkService. Следующий листинг добавляет туда возможность скачивания изображений.

Листинг 9.12. Скачивание изображений в сценарии NetworkService

...

private const string webImage = ¬ Эта константа с другими URL-адресами помещается в верхнюю часть сценария.

"http://upload.wikimedia.org/wikipedia/commons/c/c5/ Moraine_Lake_17092005.jpg";

...

public IEnumerator DownloadImage(Action<Texture2D> callback) { ¬ WWW www = new WWW(webImage);

yield return www; callback(www.texture);

}

...

234      Глава 9. Подключение игры к Интернету

Код скачивания изображений выглядит практически идентично коду скачивания данных. Основным отличием является тип метода обратного вызова; отметьте, что на этот раз обратный вызов вместо строк работает с объектами типа Texture2D. Дело в типе возвращаемого ответа: раньше скачивалась строка данных, теперь — изображение. Следующий листинг содержит код нового диспетчера. Создайте сценарий ImagesManager и скопируйте туда код.

Листинг 9.13. Диспетчер ImagesManager, запрашивающий и сохраняющий изображения

using UnityEngine;

using System.Collections;

using System.Collections.Generic; using System;

public class ImagesManager : MonoBehaviour, IGameManager { public ManagerStatus status {get; private set;}

private NetworkService _network;

private Texture2D _webImage; ¬ Переменная для сохранения скачанного изображения.

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

_network = service;

status = ManagerStatus.Started;

}

public void GetWebImage(Action<Texture2D> callback) {

if (_webImage == null) { ¬ Проверяем, нет ли уже сохраненного изображения.

StartCoroutine(_network.DownloadImage(callback));

}

else {

}

callback(_webImage); ¬ При наличии сохраненного изображения сразу активируется обратный вызов (без скачивания).

}

}

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

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

9.3. Добавление рекламного щита      235

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

Листинг 9.14. Добавление нового диспетчера в сценарий Managers.cs

...

[RequireComponent(typeof(ImagesManager))]

...

public static ImagesManager Images {get; private set;}

...

void Awake() {

Weather = GetComponent<WeatherManager>(); Images = GetComponent<ImagesManager>();

_startSequence = new List<IGameManager>(); _startSequence.Add(Weather); _startSequence.Add(Images);

StartCoroutine(StartupManagers());

}

...

В отличие от настроек диспетчера WeatherManager, при начальной загрузке диспетчера ImagesManager метод GetWebImage() автоматически не вызывается. Вместо этого код ждет процесса активации, который мы запрограммируем в следующем разделе.

9.3.2. Вывод изображения на щите

Только что написанный нами диспетчер ImagesManager ничего не сделает, пока мы его не активируем. Поэтому создадим рекламный щит, который будет вызывать методы в сценарии ImagesManager. Создайте куб и поместите его в центре сцены, введя в поля Position значения 0, 1.5, –5, а в поля Scale — значения 5, 3, 0.5. Результат показан на рис. 9.6.

Р а а

 

Р а а а а

 

 

 

Рис. 9.6. Рекламный щит до и после вывода скачанного из Интернета изображения

Мы создадим устройство, управляющееся так же, как меняющий цвета монитор из главы 8. Скопируйте сценарий DeviceOperator и свяжите его с объектом player.