How do I access Photon Teams Manager?

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

How do I access Photon Teams Manager?

Duck
2020-04-15 19:33:18

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
2020-04-16 10:55:52

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
2020-04-16 11:51:12

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
2020-04-16 12:01:25

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
2020-04-16 12:10:46

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
2020-04-16 12:17:13

public int GetTeamMembersNumber(string teamName)  
        {  
            Player[] players;  
            if (PhotonTeamsManager.Instance.TryGetTeamMembers(teamName, out players))  
            {  
                return players.Length;  
            }  
            return 0;  
        }

atomlg
2020-04-29 18:38:16

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
2020-04-29 22:34:41

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
2020-04-29 23:48:37

@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
2020-04-30 10:17:19

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
2020-05-08 14:04:25

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
2020-05-08 14:41:59

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
2020-05-08 15:24:54

@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
2020-05-26 11:37:59

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
2020-05-29 11:53:09

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
2021-05-17 18:15:39

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
2021-05-19 11:26:06

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
2021-05-19 15:47:37

Thank you for your answer, I will try and I will tell you the results

john__primitive
2021-08-18 17:01:27

@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

john__primitive
2021-08-31 00:59:38

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
2021-08-31 10:44:25

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.

Back to top