Интеграция Photon для мультиплеера мобильной игры
Photon — де-факто стандарт для Unity-мультиплеера на мобильных. Photon Realtime SDK обрабатывает транспортный уровень, матчмейкинг и управление комнатами. Но при неправильной интеграции получают: разрывы соединений при смене сети, неправильную синхронизацию объектов и счёт за трафик, который в 3 раза выше ожидаемого.
PhotonView и синхронизация объектов
PhotonView — основной компонент синхронизации. Каждый сетевой объект получает ViewID. Синхронизацию позиции и ротации через PhotonTransformView используют по умолчанию — это работает, но рассылает обновления на каждый FixedUpdate, даже если объект не двигался.
Правильный подход: IPunObservable.OnPhotonSerializeView с ручным контролем:
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
// Отправляем только если изменилось значимо
if (Vector3.Distance(_lastSentPosition, transform.position) > 0.01f)
{
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
_lastSentPosition = transform.position;
}
}
else
{
_networkPosition = (Vector3)stream.ReceiveNext();
_networkRotation = (Quaternion)stream.ReceiveNext();
}
}
На клиенте принятое _networkPosition не применяется напрямую — интерполируем через Vector3.MoveTowards или Lerp по времени пакета из PhotonMessageInfo.SentServerTime.
RPC и надёжные события
photonView.RPC — для событий, которые должны гарантированно дойти: урон, смерть, подбор предмета. RpcTarget.All рассылает всем в комнате включая отправителя. RpcTarget.Others — всем кроме.
Типичная ошибка: использовать RPC для позиционных обновлений. RPC надёжный (TCP-like поведение), добавляет overhead на подтверждение. Для позиций — PhotonNetwork.SendRate + OnPhotonSerializeView, для важных событий — RPC.
PhotonNetwork.SendRate по умолчанию 20, SerializationRate — 10. Для мобильного баланс трафика vs плавность: 15/10.
Подключение и комнаты
PhotonNetwork.ConnectUsingSettings(); // использует PhotonServerSettings asset
void OnConnectedToMaster() {
PhotonNetwork.JoinRandomOrCreateRoom(
expectedCustomRoomProperties: null,
expectedMaxPlayers: 4,
matchingType: MatchmakingMode.FillRoom,
typedLobby: null,
sqlLobbyFilter: null,
createIfNotFound: true
);
}
RoomOptions.CustomRoomPropertiesForLobby — массив ключей, видимых в лобби для фильтрации. Передавать всё в lobby-свойства не нужно: только то, по чему фильтруют (регион, режим игры, карта).
Мобильные проблемы
Смена сети. Photon SDK поддерживает PhotonNetwork.ReconnectAndRejoin() — но только если комната с playerTtl > 0. По умолчанию playerTtl = 0, игрок считается вышедшим мгновенно. Для мобильного: playerTtl = 10000 (10 секунд на reconnect).
iOS Background. При уходе в фон iOS агрессивно глушит сетевые соединения. Photon разорвётся через 5-10 секунд. Для игр, где это критично — UIBackgroundModes: voip (с осторожностью, Apple может отклонить) или graceful disconnect.
Трафик. Photon Realtime тарифицирует по CCU (одновременные пользователи). 20 CCU бесплатно. При интеграции стоит добавить Photon Dashboard в мониторинг — видно кол-во сообщений, байты, пики.
Сроки
Базовая интеграция Photon Realtime с комнатами, синхронизацией позиций и RPC: 3-7 дней. Полноценная система с матчмейкингом, custom properties и мобильной оптимизацией: 2-3 недели. Стоимость рассчитывается индивидуально.







