Падение фпс при использовании SetCustomProperties

Падение фпс при использовании SetCustomProperties

Сообщение Mikhail 11 сен 2013, 07:48

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

Проблема:
При частом использовании методов PhotonNetwork.player.SetCustomProperties (любой вызов SetCustomProperties у player) или PhotonNetwork.room.SetCustomProperties происходит резкое падение фпс. Причем, может доходить до того, что приложение совсем встает. Это же явление наблюдается в тот момент, когда другой игрок изменяет свои параметры или параметры комнаты, а на вашей машине происходит синхронизация (методы readoutStandardProperties или ReadoutProperties в последней версии фотона в скрипте NetworkingPeer).

Причины:
Во всех этих случаях, внутри функций SetCustomProperties вызывается метод SendMonoMessage (скрипт NetworkingPeer). В этом методе происходит следующее: находятся все объекты на сцене у которых есть скрипты (любые MonoBehaviour), после чего на всех этих объектах вызывается SendMessage в который передается вызов соответствующего события (OnPhotonPlayerPropertiesChanged или OnPhotonCustomRoomPropertiesChanged в данном случае).
Синтаксис:
Используется csharp
public static void SendMonoMessage(PhotonNetworkingMessage methodString, params object[] parameters)
 {
           HashSet<GameObject> haveSendGOS = new HashSet<GameObject>();
        MonoBehaviour[] mos = (MonoBehaviour[])GameObject.FindObjectsOfType(typeof(MonoBehaviour));
        for (int index = 0; index < mos.Length; index++)
        {
            MonoBehaviour mo = mos[index];
            if (!haveSendGOS.Contains(mo.gameObject))
            {
                haveSendGOS.Add(mo.gameObject);
                if (parameters != null && parameters.Length == 1)
                {
                    mo.SendMessage(methodString.ToString(), parameters[0], SendMessageOptions.DontRequireReceiver);
                }
                else
                {
                    mo.SendMessage(methodString.ToString(), parameters, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
 

Таким образом, если на сцене присутсвует большое количество объектов со скриптами, то данный метод тормозит работу всего приложения (из-за прожорливости SendMessage)

Решение:
Создание в PhotonNetwork переменной, в которой заранее задаются объекты, которым необходимо рассылать оповещения о фотоновский событиях. Это может быть что угодно (одиночный объект, массив, список, хэш). И далее в методе SendMonoMessage мы обращаемся к этой заранее проинициализированной переменной и отправляем события только на объекты указанные в ней. У меня это выглядит следующим образом:
1. в скрипт PhotonNetwork добавил public static GameObject eventsListener;

2. в скрипте NetworkPeer изменил метод SendMonoMessage на следующий:
Синтаксис:
Используется csharp
public static void SendMonoMessage(PhotonNetworkingMessage methodString, params object[] parameters)
    {
                if (parameters != null && parameters.Length == 1)
        {
                PhotonNetwork.eventsListener.SendMessage(methodString.ToString(), parameters[0], SendMessageOptions.DontRequireReceiver);
        }
        else
        {
                PhotonNetwork.eventsListener.SendMessage(methodString.ToString(), parameters, SendMessageOptions.DontRequireReceiver);
        }
}
 

Премичания:
Да, таким образом вы правите скрипты фотона, и прийдется делать это каждый раз при его обновлении (Ну если, конечно, фотоновцы сами это не поправят)
SendMonoMessage - является методом, который рассылает абсолютно все сообщения (OnCreateRoom OnJoinedRoom и так далее)
Mikhail
UNец
 
Сообщения: 24
Зарегистрирован: 03 мар 2011, 11:57

Re: Падение фпс при использовании SetCustomProperties

Сообщение gnoblin 11 сен 2013, 15:37

постил на форум фотона?
помочь с переводом?
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Падение фпс при использовании SetCustomProperties

Сообщение Mikhail 11 сен 2013, 16:19

Нет, еще не постил. Ну если есть такое желание, было бы неплохо)
Mikhail
UNец
 
Сообщения: 24
Зарегистрирован: 03 мар 2011, 11:57

Re: Падение фпс при использовании SetCustomProperties

Сообщение gnoblin 11 сен 2013, 17:50

Hello. While working with Photon Cloud I started actively using built-in hashtables (player props) for syncing data between players. And I noticed a significant FPS drop after that. Here I provide a solution for this issue.

Issue:
When frequently using PhotonNetwork.player.SetCustomProperties (a call to SetCustomProperties) or PhotonNetwork.room.SetCustomProperties methods a big fps drop happens. Up to a full stop of the execution of the application. The same issue happens when another player changes his props or room props - and the data is being synced to your client. (readoutStandardProperties or ReadoutProperties in NetworkingPeer.cs, depending on PUN version).

The cause of the issue:
In all these cases SetCustomProperties calls SendMonoMessage (NetworkingPeer.cs). The following things happen: all gameobjects on the scene with MonoBehaviours are being found, after that SendMessage is being called on them (OnPhotonPlayerPropertiesChanged or OnPhotonCustomRoomPropertiesChanged).
Синтаксис:
Используется csharp
public static void SendMonoMessage(PhotonNetworkingMessage methodString, params object[] parameters)
 {
           HashSet<GameObject> haveSendGOS = new HashSet<GameObject>();
        MonoBehaviour[] mos = (MonoBehaviour[])GameObject.FindObjectsOfType(typeof(MonoBehaviour));
        for (int index = 0; index < mos.Length; index++)
        {
            MonoBehaviour mo = mos[index];
            if (!haveSendGOS.Contains(mo.gameObject))
            {
                haveSendGOS.Add(mo.gameObject);
                if (parameters != null && parameters.Length == 1)
                {
                    mo.SendMessage(methodString.ToString(), parameters[0], SendMessageOptions.DontRequireReceiver);
                }
                else
                {
                    mo.SendMessage(methodString.ToString(), parameters, SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }
 

So if lot's of gameobjects with monobehaviours are present in scene - the game super lags because of SendMessage's bad performance.

Solution:
Create a variable in PhotonNetwork.cs where you set up the object which need to receive photon events. And then in SendMonoMessage() we access this preinitialized variable and send SendMessage only to them. My implementation:
1. public static GameObject eventsListener; added to PhotonNetwork.cs

2. SendMonoMessage method in NetworkPeer.cs changed to the following one:
Синтаксис:
Используется csharp
public static void SendMonoMessage(PhotonNetworkingMessage methodString, params object[] parameters)
    {
                if (parameters != null && parameters.Length == 1)
        {
                PhotonNetwork.eventsListener.SendMessage(methodString.ToString(), parameters[0], SendMessageOptions.DontRequireReceiver);
        }
        else
        {
                PhotonNetwork.eventsListener.SendMessage(methodString.ToString(), parameters, SendMessageOptions.DontRequireReceiver);
        }
}
 

Notes:
Yes, this way we modify PUN code, and we need to do this when updating the PUN version. I hope a built-in implementation of this can be added to PUN by exitgames.
SendMonoMessage - is the method that broadcasts absolutely all messages (OnCreateRoom OnJoinedRoom and so on)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Падение фпс при использовании SetCustomProperties

Сообщение gnoblin 11 сен 2013, 17:52

скинь плиз сюда ссылку на тему на forum.exitgames.com когда запостишь )
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Падение фпс при использовании SetCustomProperties

Сообщение gnoblin 14 ноя 2013, 20:53

запостил сам. не помню был ли пост на форуме фотона от Михаила
http://forum.exitgames.com/viewtopic.ph ... 077#p15077

Сейчас столкнулся с такой же проблемой в Голосе Припяти. Спс Михаилу)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Падение фпс при использовании SetCustomProperties

Сообщение IDoNotExist 15 ноя 2013, 12:44

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

К чему это я. Я думаю это не просто так сделали в примерах и не стоит хранить там динамические данные требующие частого обновления, например здоровье игрока, и тогда не будет падать FPS и не придется делать костыли.

Хотя это всего лишь теория, и надо бы конкретно уточнить что там можно хранить, а что не стоит.
Аватара пользователя
IDoNotExist
Адепт
 
Сообщения: 1432
Зарегистрирован: 23 мар 2011, 09:18
Skype: iamnoexist


Вернуться в Photon

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2