Culling prevents scene syncronization on new players

Hi to all. I'm making multiplayer mobile game in Unity. For optimization I decided to use culling bout only for sending, clients must receive everything. I set up everything and customized NetworkCullingHandler so it call PhotonNetwork.SetSendingEnabled instead of PhotonNetwork.SetInterestGroups. Everithing works fine for players , connected at the beginning of match, but when new player connected later, it doesn't received actual position of objects on the scene and their actual owners, that's for objects that group (photonView.group) is changed.

1. It was work fine before i started to work on culling. And still work at another scene, where culling not added.
2. After connection client receives messages as usual: changing ownership and syncronizing objects, that correct ownership he already received.
3. I manually call PhotonNetwork.SetSendingEnabled to allow all groups to receive. I call it earlier then connected to the room. Checked later, allowedReceivingGroups contains all the groups possible.
4. I was looking in the method NetworkingPeer.OnEvent at moment, client connected to the room, to be sure that sync events not just filtered, but not received at all. I saw only sync events from objects with group 0.

My assumption is that photon cloud not sending syncronization from objects in group different from 0 to new clients at connection. Can anybody help me with that? I found very few information about culling as well as about group.

I use:
Unity 2018.1.3f1, PUN plugin 1.90, Photon cloud.

Comments

  • Hi @Dimar,

    if each client should receive each event (independent of the used Interest Group), you have to use PhotonNetwork.SetInterestGroups(...); at least once in order to enable receiving messages from all Interest Groups. This basically looks like this: PhotonNetwork.SetInterestGroups(null, groups); // groups is a byte array containing all available groups you want to receive messages from.

    I set up everything and customized NetworkCullingHandler so it call PhotonNetwork.SetSendingEnabled instead of PhotonNetwork.SetInterestGroups.


    This should be fine.

    For optimization I decided to use culling bout only for sending, clients must receive everything.


    This seems to be a bit contradictory, can you explain your use case for this scenario? If you have important messages, you can always use group 0, because each client is automatically subscribed to that group and can't unsubscribe from it.

    If you haven't done this already, you can take a look at the Interest Groups documentation page to see if this gives you additional information.

  • if each client should receive each event (independent of the used Interest Group), you have to use PhotonNetwork.SetInterestGroups(...); at least once in order to enable receiving messages from all Interest Groups. This basically looks like this: PhotonNetwork.SetInterestGroups(null, groups); // groups is a byte array containing all available groups you want to receive messages from.

    Sorry, there is a typo in the point three. I actually call SetInterestGroups(null, new byte[0]); to enable receiving from all groups. Nowhere else SetInterestGroups does not called so all groups always enabled since the very connected to Photon.


    This seems to be a bit contradictory, can you explain your use case for this scenario?

    Here I optimize CPU usage, not network usage. I have quite a bit of syncronized objects on the scene, but very few of them are moving at one moment. Photon not sending changes for sleeping objects, but still serializes them regularly. Take a look at this screenshot:
    image
    It's not mine, but it's from another thread at this forum. That guy had 10 calls of PhotonView.SerializeView() and already had spikes. I have 260 calls.
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited June 2018
    Hi @Dimar,

    Thank you for choosing Photon!

    If you call PhotonNetwork.Instantiate using group > 0 then any player that will join the room after this or wasn't subscribed to the same group before will not have the object instantiated locally because buffering or caching works only in group 0.
  • @JohnTube, thank you for your time. I saw this in documentation, this isn't the case. All not synced objects are placed at the scene in design time. Also group is changed in update method, don't know if this helps.
  • Still not fixed. Any more advices?
  • Hi Dimar.

    The problem is due to how our network culling is working:

    Clients will only get a subset of events from the server, based on the Interest Group IDs.
    By default, only group 0 is being subscribed and a client will miss all events sent to a specific group, unless it deliberately subscribes to that group. Any message that doesn't get sent to the server, can't be received, of course.
    PUN is making use of this to also skip sending a few updates but it's mostly about telling the server what a client wants to receive and that's not what you need here, it seems.

    As you only want to skip serializing (and sending) updates, I would not use the Interest Groups. Instead, control what each GameObject produces in OnPhotonSerializeView.

    To do so, you could modify or extend the PhotonAnimatorView. Introduce a local variable "active" or something and check it first in your OnPhotonSerializeView. If you don't add anything to the PhotonStream, nothing gets serialized or sent.

    You may also modify PUN to not call OnPhotonSerializeView for PhotonViews that are "inactive" by your definition. This means even less performance cost but of course means a modification of PUN which you have to carry over in updates.

    Speaking of which: If you're not using the latest PUN from the Asset Store, please update :)
  • I ended up with solution partially similar to your advice and partially based on Culling.
    I extended PhotonView with additional property sendingGroup. NetworkingPeer is not calling OnPhotonSerializeView on views with not allowed sendingGroup (instead of group property). Additionally player object holds component that changing sendingGroup on PhotonViews around player.