How do I access Photon Teams Manager?

Options
Hello everyone,
I have a problem with the Photon Teams Manager in Unity. Since there is no actual documentation which helps me or I couldn't find it, but if it exists then it's hidden and hard to find. I don't know how to access this Photon Teams Manager script. I could manage my teams with Custom Properties but I think this already implemented function is better and more efficient. There is no method or namespace or even the class I can access. If I type in PhotonNetwork. and I want to write something with Team, there is no result. I have the namespaces using Photon.Pun; and using Photon.Realtime; but still nothing.
I hope someone could help me. Thank you very much!

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    edited April 2020
    Options
    Hi @Duck,

    Here is how PhotonTeamsManager should be used:

    - it's part of Photon.Pun.UtilityScripts
    - it uses player custom property PhotonTeamsManager.TeamPlayerProp ("_pt"), change it it conflicts with something you already use.
    - add PhotonTeamsManager component to the scene, preferably to a GameObject that persists across scene to avoid issues, e.g. mark it as DontDestroyOnLoad.
    - define teams in Unity Editor via PhotonTeamsManager. The same definition should be identical on all clients/builds. So if you change the team definition all clients need to be updated, e.g. change AppVersion.
    - Each PhotonTeam is identified using a unique code (byte so max 256 teams) and unique name (string).
    - Now make use of extension methods to interact with teams when joined to rooms, available methods: player.JoinTeam, player.LeaveCurrentTeam, player.SwitchTeam, player.GetPhotonTeam, player.TryGetTeamMates.
    - get events of joining / leaving teams using: PhotonTeamsManager.PlayerJoinedTeam and PhotonTeamsManager.PlayerLeftTeam.
    - you could also get available teams using PhotonTeamsManager.GetAvailableTeams.
    - other useful methods: PhotonTeamsManager.TryGetTeamByCode, PhotonTeamsManager.TryGetTeamByName, PhotonTeamsManager.TryGetTeamMembers, PhotonTeamsManager.TryGetTeamMatesOfPlayer.
  • Duck
    Options
    Hello @JohnTube ,

    Thank you very much for your answer. Now I can access this class. But I still have problems with accessing the players in one team for example. If I use PhotonTeamsManager.TryGetTeamMembers, I still can't do anything with that. I can't get the amount of players in one team for example.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @Duck,
    If I use PhotonTeamsManager.TryGetTeamMembers, I still can't do anything with that
    Check return value it needs to be true. Otherwise, the team does not exist.
    Maybe you are not joined to the room or there are no members in that team.

    Check component inspector at runtime it should show you all the info you need in Unity Editor.
  • Duck
    Options
    Hello @JohnTube .

    No, I didn't even check if it works in Runtime. I just don't know how to check the amount of players in one team.

    I want this:

    if(playersTeamBlue == playersTeamRed)
    {
    byte randomTeam = (byte)Random.Range(0, 2);
    player.JoinTeam(randomTeam);
    } else if(playersTeamBlue > playersTeamRed)
    {
    player.JoinTeam("Red");
    } else
    {
    player.JoinTeam("Blue");
    }

    And I don't know how to assign this two variables playersTeamBlue and playersTeamRed. I don't know how my script should get the amount of players in each team and assign these two variables above.
    It's just confusing without documentation.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    public int GetTeamMembersNumber(string teamName)
            {
                Player[] players;
                if (PhotonTeamsManager.Instance.TryGetTeamMembers(teamName, out players))
                {
                    return players.Length;
                }
                return 0;
            }
    
  • atomlg
    atomlg
    edited April 2020
    Options
    Hello @JohnTube . I also have a similar problem after the update, everything worked fine before, but now I can’t get the value of my team and the value of other players in the teams. At first, I turned directly to the script PhotonTeamsManager, like did it before with PunTeams (SetTeam and GetTeam) and it worked perfect. After reading the method above, I tried to write these functions to another script and accessed in the same way. But I get the values 0, null or an error after I had to join the team. The script PhotonTeamsManager is located on the Gameobject on the scene. And I can see myself in RedTeam

    https://prnt.sc/s86jpd

    What am I doing wrong and how do I get these values, as I did before using player.GetTean() from PunTeams.
    public void CheckTeam()
        {
    if (!PV.IsMine) return;
    
            PhotonNetwork.LocalPlayer.JoinTeam("Red");
    
            Debug.Log(GetTeamMembersNumber("Red")); //Get 0                                                                                                                                      
    
            Debug.Log(GetPhotonTeam(PhotonNetwork.LocalPlayer)); // Get Null
    
            Debug.Log(GetPhotonTeam(PhotonNetwork.LocalPlayer).Name); // Get Error NullReferenceException: Object reference not set to an instance of an object
    
    Debug.Log(PhotonNetwork.LocalPlayer.GetPhotonTeam());  //Get Null
        }  
    
        public static PhotonTeam GetPhotonTeam(Player player)
        {
            object teamId;
            PhotonTeam team;
            if (player.CustomProperties.TryGetValue(PhotonTeamsHendler.TeamPlayerProp, out teamId) && PhotonTeamsHendler.Instance.TryGetTeamByCode((byte)teamId, out team))
            {
                return team;
            }
            return null;
        }
    
        public int GetTeamMembersNumber(string teamName)
        {
            Player[] players;
            if (PhotonTeamsHendler.Instance.TryGetTeamMembers(teamName, out players))
            {
                return players.Length;
            }
            return 0;
        }
    
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited April 2020
    Options
    Hi @atomlg,

    Some of the methods of Photon Teams Manager or teams extensions work only when joined to a room.
    Also in PUN 2.18 (latest) we added TeamsManager.GetTeamMembersCount methods.
  • atomlg
    atomlg
    edited April 2020
    Options
    @JohnTube mod even if I called it from OnJoinedRoom
    public override void OnJoinedRoom()
        {
    
            PhotonNetwork.Instantiate(photonNetworkPlayer.name, transform.position, Quaternion.identity);
    
            PhotonNetwork.LocalPlayer.JoinTeam("Red");
            Debug.Log(PhotonNetwork.LocalPlayer.GetPhotonTeam());
        }
    
    And I get null,but If I check it in Update, I get correct team. Previously with PunTeams, everything worked instantly and there were no such delays, how can I solve this problem without using such a check?
    private void Update()
        {
    
            if (PhotonNetwork.LocalPlayer.GetPhotonTeam() != null)
            {
                Debug.Log(PhotonNetwork.LocalPlayer.GetPhotonTeam().Name);
            }
        }
    

    Even if this way it's work the same
    if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
            {
                PhotonNetwork.LocalPlayer.JoinTeam("Red");
                Debug.Log(PhotonNetwork.LocalPlayer.GetPhotonTeam());
            }
    

    And I get message
    Unexpected situation while setting team Red [1] for player #01 'Player5', updating teams for al
    l after I get null
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @atomlg,

    Photon Teams Manager relies on custom properties.
    In recent PUN versions, we changed default behaviour of setting properties locally on the client that does this.
    Before when you call SetProperties, it's done first locally then a request is sent to the server, after that the server sends an event (PropertiesChanged) to other joined actors to update them.
    Now when you call SetProperties, nothing is set locally but first a request is sent to the server, after that the server sends an event (PropertiesChanged) to ALL actors including setter/sender to update them.

    If you want to have the old behaviour: set RoomOptions.BroadcastPropsChangeToAll to false before creating rooms.

    However I recommend making use of PhotonTeamsManager events which work even for local player:
    private void OnEnable()
        {
            PhotonTeamsManager.PlayerLeftTeam += OnPlayerLeftTeam;
            PhotonTeamsManager.PlayerJoinedTeam += OnPlayerJoinedTeam;
        }
    
        private void OnPlayerLeftTeam(Player player, PhotonTeam team)
        {
            Debug.LogFormat("Player {0} left team {1}", player, team);
        }
    
        private void OnPlayerJoinedTeam(Player player, PhotonTeam team)
        {
            Debug.LogFormat("Player {0} joined team {1}", player, team);
        }
    
        private void OnDisable()
        {
            PhotonTeamsManager.PlayerLeftTeam -= OnPlayerLeftTeam;
            PhotonTeamsManager.PlayerJoinedTeam -= OnPlayerJoinedTeam;
        }
    

    Otherwise, I want repro steps for the error:
    Unexpected situation while setting team Red [1] for player #01 'Player5', updating teams for all
    Do you try to set custom actor property with the same key used by PhotonTeamsManager manually?
  • atomlg
    atomlg
    edited May 2020
    Options
    Hello @JohnTube it seems this is the only way in which I can do something after choosing a team?
    In PhotonTeamsManager
            void IMatchmakingCallbacks.OnJoinedRoom()
            {
                PhotonNetwork.LocalPlayer.JoinTeam("Red");
                this.UpdateTeams();
            }
    

    Another script
    public override void OnPlayerPropertiesUpdate(Player targetPlayer, ExitGames.Client.Photon.Hashtable changedProps)
        {
            if (!PV.IsMine) return;
            string key = TeamsHendler.TeamPlayerProp;
            object temp;
            if (changedProps.TryGetValue(key, out temp))
            {
                if (player.GetPhotonTeam() != null)
                {
    PhotonNetwork.Instantiate(player,spawnPisition[random].position,Quaternion.identity)
                }
            }
        }
    

    But when 2 players connect, I get an error :
    NullReferenceException: Object reference not set to an instance of an object
    Photon.Pun.UtilityScripts.PhotonTeamsManager.Photon.Realtime.IInRoomCallbacks.OnPlayerEnteredRoom (Photon.Realtime.Player newPlayer) (at Assets/Photon/PhotonUnityNetworking/UtilityScripts/PhotonPlayer/PhotonTeamsManager.cs:246)
    void IInRoomCallbacks.OnPlayerEnteredRoom(Player newPlayer)
            {
                PhotonTeam team = newPlayer.GetPhotonTeam();
                if (playersPerTeam[team.Code].Contains(newPlayer))
                {
    
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited May 2020
    Options
    Hi @atomlg,

    Did you update to latest PUN2? the NullReferenceException was fixed.
    Please update.

    Otherwise, do not modify PhotonTeamsManager code directly.

    Local player can join team at any time.
    Please use events as shown here.
  • atomlg
    atomlg
    edited May 2020
    Options
    @JohnTube
    I am using the latest version 2.18.1 30 April. Two players connect, they don’t even choose a team and I just get this error. I don't change anything. I have gameobject on scene with PhotonTeamsManager script.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @atomlg,

    This could be related to a known Unity issue, sometimes old packages are stuck in the local offline cache and updates do not occur at all or not properly.
    Remove PUN asset package locally first and try downloading / importing again to fix this.
    paths are here.
  • atomlg
    atomlg
    edited May 2020
    Options
    Hello @JohnTube . Thank you,this problem is solved. Can I ask how can I send rpc only for my teammates? I can use TryGetTeamMatesOfPlayer, but how send RPC to every one of them in Player[] teamMates?
    Only this way ?
    for(int i = 0; i < players.Length; i++)
                {
                    _photonView.RPC("FinanceSystemAddAmount", players[i]);
                }
    

    But if someone join team later he don't recive this RPC. I have 2 banks for different teams. And I need the information to be updated for the both teams in different ways.And players from one team could see and change information only of their bank.
  • Ragda_06
    Options
    Hello everyone, I would like to tell you a bit about my game to give you a little context about it.

    My game is about multiplayer pirate ships. Each ship carries its crew and there is a captain for each ship.
    There is a maximum of 4 boats with 5 crew members and as mentioned before there is a captain for each boat.

    As you can see there are many variables to consider. However, I was able to solve some thanks to this post.
    I have been able to instantiate a given player in their respective spawn point and each player knows which team they belong to through PunRPC.
    The part of being captain or rower and that each player knows his role, I also want to achieve it through PunRPC, however,
    I want to validate that each team knows that there is already a captain so as not to break the game.

    I still don't know how to achieve that, since at one point in the game each player can choose their role and the team they can join,
    but I need to let them know if there is already a captain in the team, otherwise they can be captain in that team or choose another team that does not have a captain.

    Any idea how to do this validation. It is a bool data type but as a Czech in each player who joined the team which role he chose.

    At the moment everyone can join and choose their role and even have more than one captain, this is not ideal.

    Thanks for your time and I hope you can help me.

    PD: Excuse me, my English is not very good and I used a translator
  • Tobias
    Options
    The PunTeams code is using Custom Properties to sync who is in which team. When you use RPCs instead, the values don't become part of the game state and joining players will not know.

    Custom Properties also have a feature called Check and Swap (CAS). It tells the server to update a key only if some condition is met. In your case: Use a property per ship, which stores the captain. E.g. using a brief string key: "c1". Now, you can set "c1" with SetCustomProperties() and everyone will know (with a slight delay, ofc).

    This is related:
    https://doc.photonengine.com/en-us/pun/v2/gameplay/synchronization-and-state#custom_properties
  • Ragda_06
    Options
    Thank you for your answer, I will try and I will tell you the results
  • @JohnTube @Tobias I'm running this code:
    PhotonTeamsManager.PlayerJoinedTeam += PlayerJoinedTeam;
    PhotonTeamsManager.PlayerLeftTeam += PlayerLeftTeam;
    
    void PlayerJoinedTeam(Player player, PhotonTeam photonTeam)
    {
        Debug.Log(player.UserId);
    }
    
    void PlayerLeftTeam(Player player, PhotonTeam photonTeam)
    {
        Debug.Log(player.UserId);
    }
    

    but the actions are never firing off when a player joins a team. The PhotonTeamsManager has teams listed and I can see the team member appearing on the component in the Unity Editor at runtime. What am I doing wrong?

    Thank you
  • Update: it does appear that the timing of joining a room is important for these events to fire off. So joining a team is still possible outside of a room, but the events do not fire off. But if the join team call happens after successfully entering a room, then the events are fired.
  • Tobias
    Options
    You have to be in a room to join a team, yes. Any communication with other players will only work in-room.
    Sorry that wasn't clear.