Interest group does nothing ?

Slyp
Slyp
Hello,
I am a new user of photon PUN in the process of making a position based interest management system for a 2D game, I'm doing this in my code:
byte[] groupArray = InterestGroupManager.GetInterestGroupArray(transform.position);

PhotonNetwork.SetInterestGroups(new byte[0], groupArray);  

PhotonNetwork.SetSendingEnabled(new byte[0], groupArray);

photonView.Group = InterestGroupManager.GetMyGroup(transform.position);
With InterestGroupManager being a class that associate cells on the map to a group Id.

But it doesn't work how I understand it would, I still receive both OnPhotonSerializeView and RPCs from object that are not in the same interest group.
Also, I don't understand the reason for photonView.Group, I tried looking at both the documentation and the culling demo for PUN 1 but I still don't understand.

What am I doing wrong? Can only event be use with interest groups ? Thanks for the help !

Comments

  • Hi,
    I have the same issue. I also can't make Interest Groups to work, the only thing that works is the PhotonNetwork.Instantiate when there is a group assigned ( != 0 ) and your client is subscribed to listen to the same group.

    In the documentation also said that when you use PhotonNetwork.Instantiate the photonview will automatically get the same group assigned but this doesn't happen, it keeps as group 0.

    RPCs and RaiseEvents also don't work, the messages are sent but anybody else can't listen at them as supposed when your client is subscribed to the same groups.

    I think that there is a bug with the Interest Groups.

    Please help!!
  • I did some more digging, I got it to work more by not using "new byte[0]" but a full array for the disabled groups,

    But now I seems to be in the same case as you, I can't get RPC from one object to the same one,
    also, for some reason when my second player is far away enough (not in the same group as the first player) I will get less updates on it's position, but still get some. It seems to be buggy indeed. Any help would be appreciated !

    If it's really a bug then using PUN 1 may be a solution ?
  • Just to clarify, I've been using PUN v2.15.

    I have made a lot o test only to figure it out what is happening and if magically I can find a solution, but nothing :(

    For example, separately I tested all of these options:
    PhotonNetwork.SetInterestGroups(new byte[0], new byte[] { 1 });
    PhotonNetwork.SetInterestGroups(null, new byte[0]);
    PhotonNetwork.SetInterestGroups( 1, true);
    In any of all cases I can't get it working. The only working thing is when using PhotonNetwork.Instantiate with an interest group, for example, like this:
    PhotonNetwork.Instantiate("PlayerPrefab", position, rotation, 1);
    But it also buggy because it doesn't assign the photonviews that the new instance have to the same group as it's meant to be, and also, this only work for remote clients but not for the local client, for example, If I do something like this:
    PhotonNetwork.SetInterestGroups( 1, false); // This is for all clients
    if(PhotonNetwork.IsMasterClient)
    PhotonNetwork.Instantiate("PlayerPrefab", position, rotation, 1); // This is only for Local Master client
    It doesn't spawn any GameObject in the remote client, but it does in the local client :/

    And last, for RPC's and RiseEvents I can't make them work even if I use them locally, for example, like this:
    object[] content = new object[] { "Hello" };
    RaiseEventOptions raiseEventOptions = new RaiseEventOptions() { Receivers = ReceiverGroup.All , InterestGroup = 1 };
    SendOptions sendOptions = new SendOptions { DeliveryMode = DeliveryMode.Unreliable };
    PhotonNetwork.RaiseEvent(1, content, raiseEventOptions, sendOptions);
    It's a perfectly working event when using InterestGroup = 0, but as soon as I change it to InterestGroup = 1 it stops working.

    Going back to PUN 1 is not a solution for me, I've already a heavily advanced developed project and I can't go back and redoing all of this :s

    Again, PLEASE HELP!!!
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited October 2019
    Hi @Slyp, @MikeMuorte,

    Thank you for choosing Photon and for reporting this.
    I will try to reproduce and get back to you here.

    Before going into details, what are you trying to achieve with interest groups?
    Do you have to combine interest groups with PhotonNetwork.Instantiate/PhotonView/RPC?

    On the other hand, maybe expectations need to be adjusted since:

    Anything sent in interest groups other than 0 cannot be cached/buffered.
    So for instance, if you call PhotonNetwork.Instantiate and pass an interest group other than 0, any actor who will join or rejoin after the call will not have the object instantiated on its respective client.

    Interest groups change operation calls do not have good feedback from the server or at least that's my own personal opinion. It's not easy to reliably keep track of which groups the client is subscribed to at a given time. We just go for the optimistic approach that all operation calls to change the groups went successfully or maybe a 'brute force' way of repeating the calls to make sure.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi,

    I think it was decided to always use the interest goup 0 for the instantiation event itself (to guarantee the instantiation happens for late joiners or rejoiners) but after that we set all the interest group of PhotonView in the instantiated object to the value used in the instantiate call.

    The first part is OK.
    The second part is not there.

    So could you add the missing line and retry:

    The missing line is:

    photonViews[i].Group = parameters.group;

    Inside "Assets\Photon\PhotonUnityNetworking\Code\PhotonNetwork.cs"
    inside "NetworkInstantiate"

    before:
    for (int i = 0; i < photonViews.Length; i++)
                {
                    if (localInstantiate)
                    {
                        // when this client instantiates a GO, it has to allocate viewIDs accordingly.
                        // SCENE objects are created as actorNumber 0 (no matter which number this player has).
                        parameters.viewIDs[i] = (sceneObject) ? AllocateViewID(0) : AllocateViewID(parameters.creator.ActorNumber);
                    }
    
                    photonViews[i].didAwake = false;
                    photonViews[i].ViewID = 0;
    
                    photonViews[i].Prefix = parameters.objLevelPrefix;
                    photonViews[i].InstantiationId = parameters.viewIDs[0];
                    photonViews[i].isRuntimeInstantiated = true;
                    photonViews[i].InstantiationData = parameters.data;
    
                    photonViews[i].didAwake = true;
                    photonViews[i].ViewID = parameters.viewIDs[i];    // with didAwake true and viewID == 0, this will also register the view
                }
    after
    for (int i = 0; i < photonViews.Length; i++)
                {
                    if (localInstantiate)
                    {
                        // when this client instantiates a GO, it has to allocate viewIDs accordingly.
                        // SCENE objects are created as actorNumber 0 (no matter which number this player has).
                        parameters.viewIDs[i] = (sceneObject) ? AllocateViewID(0) : AllocateViewID(parameters.creator.ActorNumber);
                    }
    
                    photonViews[i].didAwake = false;
                    photonViews[i].ViewID = 0;
    
                    photonViews[i].Prefix = parameters.objLevelPrefix;
                    photonViews[i].InstantiationId = parameters.viewIDs[0];
                    photonViews[i].isRuntimeInstantiated = true;
                    photonViews[i].InstantiationData = parameters.data;
    
                    photonViews[i].didAwake = true;
                    photonViews[i].ViewID = parameters.viewIDs[i];    // with didAwake true and viewID == 0, this will also register the view
    
                    photonViews[i].Group = parameters.group;
                }
  • JohnTube
    JohnTube ✭✭✭✭✭
    One more thing: using an interest group other than 0 means you cannot receive your own events.
    So RPCs with RpcTarget.AllViaServer or RaiseEvent with ReceiverGroup.All won't work and the client who calls the RPC or the RaiseEvent will not receive his own event.
  • Hi @JohnTube

    Thank you very much for your answer.

    I already had reached the same fix you purposed for the photonview inside the PhotonNetwork.cs script, I'm glad that I was in the right way, I don't like to mess up with the photon's scripts cause it's more easy to get an unexpected behaviour than a useful fix :D

    So, even if the local client is subscribed to the same group, other than 0, can't listen to it's own calls?

    What I'm trying to archive is a game with shooting mechanics, but the most important thing is that there will be different types of clients, some of them are the players that shoot (doing and receiving calls using group 1), others will be only viewers (only receiving calls from group 1) and others will be a configuration panel with only UI for each of the players (only doing calls to group 1 and receiving calls from group 2).

    In the UI clients I don't want to have all the networking objects been instantiated in the background cause nobody will see them through this type of client. In this game I'm not using any cache or buffering in any of the logic of the calls I'm trying to do, as it's said in the documentation.

    The issue appears, for example, when using a shooting player client and trying to shoot or even trying to move using the PhotonTransformView through a photonview with the group 1. The remote client of the same type, using group 1, doesn't receive any call or movement sync.
  • Hello, thanks for the reply !

    For my part, I'm making a game with a functioning close to a .io game.
    the camera is fixed on the player, and there can be no interactions between players that are too far away.
    The only informations that I would need to be global would be some instantiation data per player (like it's name), it's score during the game (for a scoreboard) and equipment changes with a RPC (that should be buffered and reliable) (except if I can detect a new player in range and have it send it's data to the other at that moment)

    I wanted to use interest group to split my player depending on where they are, in order to reduce server load increasing my number of player, and to prevent cheating.
    My plan was to split my map into multiple cells (less than 256), and have clients dynamically suscribe to different interest groups depending on their position.
    Is this a good/useful approach ?

    I don't think the fact that group calls can't be buffered and interest group reliability is an issue for me, as call that would be dependent on group would be one time action that could be missed (especially if in range of group but out of the screen).
    Should I have two photonView on my object, one for globals RPCs and one for "local" ones ?
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited October 2019
    Hi @MikeMuorte,

    The issue appears, for example, when using a shooting player client and trying to shoot or even trying to move using the PhotonTransformView through a photonview with the group 1. The remote client of the same type, using group 1, doesn't receive any call or movement sync.
    After applying the fix I mentioned in the previous post above I cannot reproduce this. I'm able to synchronize a GameObject with PhotonTransformView and PhotonView instantiated on group 1. Make sure all remote client(s) that need to receive the sync events are subscribed to the interest group 1!

    Hi @Slyp,

    Is this a good/useful approach ?
    Yes of course.
    Should I have two photonView on my object, one for globals RPCs and one for "local" ones ?
    No why? All PhotonViews attached to the same prefab will have the same interest group set in the Instantiate call. Changing the PhotonView.Group later will not be synchronized and should not be done now. Maybe we will implement this later.

    @MikeMuorte @Slyp

    The building blocks from the "Culling Demo" from PUN Classic are CullArea and CullingHandler are part of PUN2 can still be used as-is or as inspiration.
  • I looked at CullArea and CullAreaHandler and managed to work around my problem, an obvious mistake I made was not checking for pView.IsMine in some parts of my interest group script...

    Thanks a lot for the help !
  • pamplins
    pamplins
    edited April 2021
    Hi @JohnTube or any buddy, I am trying to show an object (a cube for now) to people who are in the same specific group (different from 0). From what I have been able to read in the forum, I understand that if a player X, instantiates an object (with group 3 for example) and another player Y changes group, from 0 (by default) to 3, he will not be able to see the instantiated object from group 3 because the object is not synchronized at run time. How can I create an object so that the Y player can see it in real time please?

    The idea is to be able to create an object for certain people in a group and then, for some reason in the game, remove them from that group to assign the player in another. That is, see certain things in the game from the group you are in. Maybe I'm doing this with grups and I shouldn't. There is another way?

    I have searched the documentation but have not found any information on this.

    Can you help me please? Thanks in advance.

    I have already found my mistake. I was instantiating the item before modifying the group to the players. If I modify group first and then intancio, it works perfectly. Thank you