Unity #
Подключение #
Скачайте актуальный .unitypackage
cо страницы релизов на github.com и импортируйте в проект.
Для корректной работы необходимо импортироавать все файлы, кроме папки Examples
.
Ее можно импортировать по желанию.
В ней есть сцена с примерами использования.
Инициализация #
Когда игра загружена — плагин уже проинициализирован. Ничего дополнительно делать не нужно.
Сборка #
Для корректной работы плагина необходимо выбрать соответствующий WebGL Template
.
![](/images/unity/template.png)
Здесь есть ряд настроек внешнего вида:
Overlay Background Color
— цвет фона.
Progress Bar Background Color
— цвет фона загрузочной полосы.
Progress Bar Fill Color
— цвет самой полосы.
Game Distribution Game ID
— ID игры, если публикуете на GameDistribution.
VK Play Game ID
— ID игры, если публикуете на VK Play.
Adsgram Block ID
— ID рекламного блока, если публикуете в Telegram и используете adsgram.ai.
Цвет задаётся в формате HEX. Например, чёрный — #000000
. Для значения по умолчанию нужно поставить знак -
.
Чтобы заменить иконку — просто замените файл WebGLTemplates/Bridge/icon.png
.
⚠️ Предупреждение
При загрузке файлов на Crazy Games в пункте Game Type нужно выбрать HTML5.
Информация о платформе #
ID платформы #
Bridge.platform.id
Возвращает ID платформы, на которой запущена игра в данный момент.
Возможные значения: playgama
, crazy_games
, game_distribution
, yandex
, wortal
, playdeck
, telegram
, vk
, ok
, vk_play
, absolute_games
, mock
.
Язык #
Bridge.platform.language
Если платформа предоставляет данные об языке пользователя — то это будет язык, который установлен у пользователя на платформе. Если не предоставляет — это будет язык браузера пользователя.
Формат: ISO 639-1. Пример: ru
, en
.
Параметр из адресной строки #
Bridge.platform.payload
С помощью данного параметра можно в ссылку на игру встраивать какую-либо вспомогательную информацию.
Платформа | Формат ссылки |
---|---|
Playgama | — |
Crazy Games | crazygames.com/game/example?payload=your-info |
Game Distribution | — |
Yandex | yandex.com/games/play/183100?payload=your-info |
Wortal | — |
PlayDeck | — |
Telegram | — |
VK Play | — |
VK | vk.com/app8056947#your-info |
OK | — |
Absolute Games | — |
Mock | site.com/game?payload=your-info |
Информация о домене #
Bridge.platform.tld
Если данных нет –
null
. Если данные есть – com
, ru
, etc.
Отправка сообщения платформе #
Bridge.platform.SendMessage(PlatformMessage.GameReady);
Сообщение | Описание |
---|---|
GameReady | Игра загрузилась, все загрузочные экраны прошли, игрок может взаимодействовать с игрой. |
InGameLoadingStarted | Началась какая-либо загрузка внутри игры. Например, когда идёт загрузка уровня. |
InGameLoadingStopped | Загрузка внутри игры окончена. |
GameplayStarted | Начался геймплей. Например, игрок зашёл в уровень с главного меню. |
GameplayStopped | Геймплей закончился/приостановился. Например, при выходе с уровня в главное меню, открытии меню паузы и т.д. |
PlayerGotAchievement | Игрок достиг особенного момента. Например, победил босса, установил рекорд и т.д. |
Серверное время #
private void Start()
{
Bridge.platform.GetServerTime(OnGetServerTimeCompleted);
}
private void OnGetServerTimeCompleted(DateTime? result)
{
if (result.HasValue)
{
Debug.Log(result.Value);
}
}
Информация о девайсе #
Тип девайса #
Bridge.device.type
Возвращает тип девайса, с которого пользователь запустил игру. Возможные значения: mobile
, tablet
, desktop
, tv
.
Информация об игроке #
Поддержка авторизации #
Bridge.player.isAuthorizationSupported
Возможные значения:
true
,
false
.
Авторизован ли игрок в данный момент #
Bridge.player.isAuthorized
Возможные значения:
true
,
false
.
ID игрока #
Bridge.player.id
Если данных нет –
null
. Если данные есть – данные в формате string
.
Имя игрока #
Bridge.player.name
Если данных нет –
null
. Если данные есть – данные в формате string
.
Аватар игрока #
Bridge.player.photos
Возможные значения: пустой массив, массив с ссылками на изображения.
Авторизация игрока #
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("scopes", true);
break;
}
Bridge.player.Authorize(options, OnAuthorizePlayerCompleted);
}
private void OnAuthorizePlayerCompleted(bool success)
{
if (success)
{
// Игрок успешно авторизован
}
else
{
// Ошибка, что-то пошло не так
}
}
Информация об игре #
Текущее состояние видимости #
Bridge.game.visibilityState
Возвращает текущее состояние видимости игры (вкладки с игрой).
Возможные значения: visible
, hidden
.
📝 Примечание
Нужно реагировать на изменение состояния видимости. Например, выключать звук в игре приhidden
и включать приvisible
.
// Изменение состояния видимости можно отслеживать, подписавшись на событие
private void Start()
{
Bridge.game.visibilityStateChanged += OnGameVisibilityStateChanged;
}
private void OnGameVisibilityStateChanged(VisibilityState state)
{
switch (state)
{
case VisibilityState.Visible:
// Вкладка с игрой видима
break;
case VisibilityState.Hidden:
// Вкладка с игрой скрыта
break;
}
}
Пользовательские данные #
Есть два типа хранилища: локальноеlocal_storage
и внутреннее platform_internal
. При записи в локальное — данные сохраняются у игрока на конкретном девайсе, при записи во внутреннее — данные сохраняются на серверах платформы.
Тип хранилища по умолчанию #
Bridge.storage.defaultType
Тип хранилища, который используется по-умолчанию в конкретный момент на конкретной платформе. Возможные значения: local_storage
, platform_internal
.
Проверка на поддержку #
Bridge.storage.IsSupported(StorageType.LocalStorage)
Bridge.storage.IsSupported(StorageType.PlatformInternal)
Возможные значения:
true
,
false
.
Проверка на доступность #
Bridge.storage.IsAvailable(StorageType.LocalStorage)
Bridge.storage.IsAvailable(StorageType.PlatformInternal)
Возможные значения:
true
,
false
.
Загрузка данных #
// Получить данные по ключу
private void Start()
{
Bridge.storage.Get("level", OnStorageGetCompleted);
}
private void OnStorageGetCompleted(bool success, string data)
{
// Загрузка произошла успешно
if (success)
{
if (data != null)
{
Debug.Log(data);
}
else
{
// Данных по ключу level нет
}
}
else
{
// Ошибка, что-то пошло не так
}
}
// Получить данные по нескольким ключам
private void Start()
{
Bridge.storage.Get(new List<string>() { "level", "coins" }, OnStorageGetCompleted);
}
private void OnStorageGetCompleted(bool success, List<string> data)
{
// Загрузка произошла успешно
if (success)
{
if (data[0] != null)
{
Debug.Log($"Level: {data[0]}");
}
else
{
// Данных по ключу level нет
}
if (data[1] != null)
{
Debug.Log($"Coins: {data[1]}");
}
else
{
// Данных по ключу coins нет
}
}
else
{
// Ошибка, что-то пошло не так
}
}
// Получить данные из конкретного хранилища
private void Start()
{
Bridge.storage.Get("level", OnStorageGetCompleted, StorageType.LocalStorage);
}
private void OnStorageGetCompleted(bool success, string data)
{
// Загрузка произошла успешно
if (success)
{
if (data != null)
{
Debug.Log(data);
}
else
{
// Данных по ключу level нет
}
}
else
{
// Ошибка, что-то пошло не так
}
}
Сохранение данных #
// Сохранить данные по ключу
private void Start()
{
Bridge.storage.Set("level", "dungeon_123", OnStorageSetCompleted);
}
private void OnStorageSetCompleted(bool success)
{
Debug.Log($"OnStorageSetCompleted, success: {success}");
}
// Сохранить данные по нескольким ключам
private void Start()
{
var keys = new List<string>() { "level", "is_tutorial_completed", "coins" };
var data = new List<object>() { "dungeon_123", true, 12 };
Bridge.storage.Set(keys, data, OnStorageSetCompleted);
}
// Сохранить данные в конкретное хранилище
private void Start()
{
Bridge.storage.Set("level", "dungeon_123", OnStorageSetCompleted, StorageType.LocalStorage);
}
Удаление данных #
// Удалить данные по ключу
private void Start()
{
Bridge.storage.Delete("level", OnStorageDeleteCompleted);
}
private void OnStorageDeleteCompleted(bool success)
{
Debug.Log($"OnStorageDeleteCompleted, success: {success}");
}
// Удалить данные по нескольким ключам
private void Start()
{
var keys = new List<string>() { "level", "is_tutorial_completed", "coins" };
Bridge.storage.Delete(keys, OnStorageDeleteCompleted);
}
// Удалить данные из конкретного хранилища
private void Start()
{
Bridge.storage.Delete("level", OnStorageDeleteCompleted, StorageType.LocalStorage);
}
Если при работе с данными не передавать конкретный тип хранилища, то используется тип хранилища по умолчанию Bridge.storage.defaultType
.
Реклама #
Banner #
Поддерживается ли баннер #
Bridge.advertisement.isBannerSupported
Возможные значения:
true
,
false
.
Показать баннер #
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "vk":
options.Add("position", "bottom");
options.Add("layoutType", "resize");
options.Add("canClose", false);
break;
}
Bridge.advertisement.ShowBanner(options);
}
Скрыть баннер #
Bridge.advertisement.HideBanner()
Состояние баннера #
Bridge.advertisement.bannerState
Текущее состояние баннера. Возможные значения: loading
, shown
, hidden
, failed
.
// Отслеживать изменение состояния можно подписавшись на событие
private void Start()
{
Bridge.advertisement.bannerStateChanged += OnBannerStateChanged;
}
private void OnBannerStateChanged(BannerState state)
{
Debug.Log(state);
}
Interstitial #
Межстраничная реклама. Обычно показывается в момент загрузки уровня/поражения и т.д.Минимальный интервал между показами #
// Значение по умолчанию = 60 секунд
Bridge.advertisement.minimumDelayBetweenInterstitial
Между показами Interstitial-рекламы нужно соблюдать временные интервалы. Например, Yandex просто не покажет рекламу если вызывать слишком часто, а VK будет показывать так часто, как вызывается метод.
Для удобства, в данном SDK есть встроенный механизм таймера между показами. Вам нужно лишь указать нужный интервал и можно дёргать метод показа рекламы сколько угодно.
private void Start()
{
// Установить минимальный интервал
Bridge.advertisement.SetMinimumDelayBetweenInterstitial(30);
}
Состояние рекламы #
Bridge.advertisement.interstitialState
Текущее состояние рекламы. Возможные значения: loading
, opened
, closed
, failed
.
📝 Примечание
Нужно реагировать на изменение состояния рекламы. Например, выключать звук в игре приopened
и включать приclosed
иfailed
.
// Отслеживать изменение состояния можно подписавшись на событие
private void Start()
{
Bridge.advertisement.interstitialStateChanged += OnInterstitialStateChanged;
}
private void OnInterstitialStateChanged(InterstitialState state)
{
Debug.Log(state);
}
Показать рекламу #
private void Start()
{
Bridge.advertisement.ShowInterstitial();
}
Rewarded #
Реклама за вознаграждение.Состояние рекламы #
Bridge.advertisement.rewardedState
Текущее состояние рекламы. Возможные значения: loading
, opened
, closed
, rewarded
, failed
.
📝 Примечание
Нужно реагировать на изменение состояния рекламы. Например, выключать звук в игре приopened
и включать приclosed
иfailed
.
⚠️ Предупреждение
Награду игроку нужно выдавать только при наступлении состоянияrewarded
.
// Отслеживать изменение состояния можно подписавшись на событие
private void Start()
{
Bridge.advertisement.rewardedStateChanged += OnRewardedStateChanged;
}
private void OnRewardedStateChanged(RewardedState state)
{
Debug.Log(state);
}
Показать рекламу #
Bridge.advertisement.ShowRewarded()
AdBlock #
Проверить включен ли блокировщик рекламы.private void Start()
{
Bridge.advertisement.CheckAdBlock(OnCheckAdBlockCompleted);
}
private void OnCheckAdBlockCompleted(bool result)
{
Debug.Log(result); // true or false
}
Социальные взаимодействия #
Поделиться #
Bridge.social.isShareSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "vk":
options.Add("link", "https://vk.com/mewton.games");
break;
}
Bridge.social.Share(options, OnShareCompleted);
}
private void OnShareCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Вступить в сообщество #
Bridge.social.isJoinCommunitySupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "vk":
options.Add("groupId", 199747461);
break;
case "ok":
options.Add("groupId", 62984239710374);
break;
}
Bridge.social.JoinCommunity(options, OnJoinCommunityCompleted);
}
private void OnJoinCommunityCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Пригласить друзей #
Bridge.social.isInviteFriendsSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "ok":
options.Add("text", "Hello World!");
break;
}
Bridge.social.InviteFriends(options, OnInviteFriendsCompleted);
}
private void OnInviteFriendsCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Опубликовать пост #
Bridge.social.isCreatePostSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "vk":
options.Add("message", "Hello World!");
options.Add("attachments", "photo-199747461_457239629");
break;
case "ok":
var media = new object[]
{
new Dictionary<string, object>
{
{ "type", "text" },
{ "text", "Hello World!" },
},
new Dictionary<string, object>
{
{ "type", "link" },
{ "url", "https://apiok.ru" },
},
new Dictionary<string, object>
{
{ "type", "poll" },
{ "question", "Do you like our API?" },
{
"answers",
new object[]
{
new Dictionary<string, object>
{
{ "text", "Yes" },
},
new Dictionary<string, object>
{
{ "text", "No" },
}
}
},
{ "options", "SingleChoice,AnonymousVoting" },
},
};
options.Add("media", media);
break;
}
Bridge.social.CreatePost(options, OnCreatePostCompleted);
}
private void OnCreatePostCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Добавить в избранное #
Bridge.social.isAddToFavoritesSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
Bridge.social.AddToFavorites(OnAddToFavoritesCompleted);
}
private void OnAddToFavoritesCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Добавить на рабочий стол #
Bridge.social.isAddToHomeScreenSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
Bridge.social.AddToHomeScreen(OnAddToFavoritesCompleted);
}
private void OnAddToHomeScreenCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Оценить игру #
Bridge.social.isRateSupported
Поддерживается ли функционал на платформе.
Возможные значения:
true
,
false
.
private void Start()
{
Bridge.social.Rate(OnRateCompleted);
}
private void OnRateCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Внешние ссылки #
Bridge.social.isExternalLinksAllowed
Разрешены ли внешние ссылки на платформе.
Возможные значения:
true
,
false
.
Лидерборды #
Поддержка #
Bridge.leaderboard.isSupported
Возможные значения:
true
,
false
.
Нативный popup #
Bridge.leaderboard.isNativePopupSupported
Поддерживается ли нативный popup.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "vk":
options.Add("userResult", 42);
options.Add("global", true);
break;
}
Bridge.leaderboard.ShowNativePopup(options, OnShowNativePopupCompleted);
}
private void OnShowNativePopupCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Очки игрока #
Запись #
Bridge.leaderboard.isSetScoreSupported
Поддерживается ли запись очков игрока с клиента.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("score", 42);
options.Add("leaderboardName", "YOUR_LEADERBOARD_NAME");
break;
}
Bridge.leaderboard.SetScore(options, OnSetScoreCompleted);
}
private void OnSetScoreCompleted(bool success)
{
if (success)
{
// Операция прошла успешно
}
else
{
// Произошла ошибка
}
}
Чтение #
Bridge.leaderboard.isGetScoreSupported
Поддерживается ли чтение очков игрока.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("leaderboardName", "YOUR_LEADERBOARD_NAME");
break;
}
Bridge.leaderboard.GetScore(options, OnGetScoreCompleted);
}
private void OnGetScoreCompleted(bool success, int score)
{
if (success)
{
// Данные успешно получены
Debug.Log(score);
}
else
{
// Что-то пошло не так
}
}
Записи таблицы #
Bridge.leaderboard.isGetEntriesSupported
Поддерживается ли чтение полной таблицы.
Возможные значения:
true
,
false
.
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("leaderboardName", "YOUR_LEADERBOARD_NAME");
options.Add("includeUser", true);
options.Add("quantityAround", 10);
options.Add("quantityTop", 10);
break;
}
Bridge.leaderboard.GetEntries(options, OnGetEntriesCompleted);
}
private void OnGetEntriesCompleted(bool success, List<Dictionary<string, string>> entries)
{
Debug.Log($"OnGetEntriesCompleted, success: {success}, entries:");
if (success)
{
switch (Bridge.platform.id)
{
case "yandex":
foreach (var entry in entries)
{
Debug.Log("ID: " + entry["id"]);
Debug.Log("Score: " + entry["score"]);
Debug.Log("Rank: " + entry["rank"]);
Debug.Log("Name: " + entry["name"]);
Debug.Log("Photo: " + entry["photo"]);
}
break;
}
}
}
Внутриигровые покупки #
Существуют два типа покупок — постоянные (например, отключение рекламы) и расходуемые (например, внутриигровые монеты).Поддержка #
Bridge.payments.isSupported
Возможные значения:
true
,
false
.
Покупка #
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("id", "PURCHASE_ID");
break;
}
Bridge.payments.Purchase(options, OnPurchaseCompleted);
}
private void OnPurchaseCompleted(bool success)
{
Debug.Log(success);
}
Расходование #
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
options.Add("purchaseToken", "PURCHASE_TOKEN");
break;
}
Bridge.payments.ConsumePurchase(options, OnConsumePurchaseCompleted);
}
private void OnConsumePurchaseCompleted(bool success)
{
Debug.Log(success);
}
Каталог всех товаров #
private void Start()
{
Bridge.payments.GetCatalog(OnGetCatalogCompleted);
}
private void OnGetCatalogCompleted(bool success, List<Dictionary<string, string>> catalog)
{
Debug.Log($"OnGetCatalogCompleted, success: {success}, items:");
if (success)
{
switch (Bridge.platform.id)
{
case "yandex":
foreach (var item in catalog)
{
Debug.Log("ID: " + item["id"]);
Debug.Log("Title: " + item["title"]);
Debug.Log("Description: " + item["description"]);
Debug.Log("Image URI: " + item["imageURI"]);
Debug.Log("Price: " + item["price"]);
Debug.Log("Price Currency Code: " + item["priceCurrencyCode"]);
Debug.Log("Price Currency Image: " + item["priceCurrencyImage"]);
Debug.Log("Price Value: " + item["priceValue"]);
}
break;
}
}
}
Список купленных товаров #
private void Start()
{
Bridge.payments.GetPurchases(OnGetPurchasesCompleted);
}
private void OnGetPurchasesCompleted(bool success, List<Dictionary<string, string>> purchases)
{
Debug.Log($"OnGetPurchasesCompleted, success: {success}, items:");
if (success)
{
switch (Bridge.platform.id)
{
case "yandex":
foreach (var purchase in purchases)
{
Debug.Log("Product ID: " + purchase["productID"]);
Debug.Log("Purchase Token: " + purchase["purchaseToken"]);
}
break;
}
}
}
Удаленная конфигурация #
С помощью удаленной конфигурации вы можете управлять настройками вашей игры не выпуская обновлений.Поддержка #
Bridge.remoteConfig.isSupported
Возможные значения:
true
,
false
.
Загрузка значений #
private void Start()
{
var options = new Dictionary<string, object>();
switch (Bridge.platform.id)
{
case "yandex":
var clientFeatures = new object[]
{
new Dictionary<string, object>
{
{ "name", "levels" },
{ "value", "5" },
}
};
options.Add("clientFeatures", clientFeatures);
break;
}
Bridge.remoteConfig.Get(options, OnRemoteConfigGetCompleted);
}
private void OnRemoteConfigGetCompleted(bool success, List<Dictionary<string, string>> data)
{
if (success)
{
foreach (var keyValuePair in data)
{
Debug.Log($"key: { keyValuePair.Key }, value: { keyValuePair.Value }");
}
}
}