Hi,
I cannot find the solution to my Updating problem.
When I add a second player, the leaderbaord display on the second player does not get the totalCoin from the first player. They are both at 0 even if I gathered 30 coins beforehand. When the first player gather a new coin, the leaderboard (on the second player window) update fine. The host player is always fine.
public class LeaderBoardScript : NetworkBehaviour
{
[SerializeField] private Transform leaderBoardEntityHolder;
[SerializeField] private LeaderBoardEntityDisplay leaderBoardEntityPrefab;
[SerializeField] private int entitiesToDisplay = 4;
private NetworkList<LeaderboardEntityState> leaderboardEntities;
private List<LeaderBoardEntityDisplay> entitiesDisplays = new List<LeaderBoardEntityDisplay> ();
private void Awake()
{
leaderboardEntities = new NetworkList<LeaderboardEntityState>();
}
public override void OnNetworkSpawn()
{
if(IsClient)
{
leaderboardEntities.OnListChanged += HandleLeaderboardEntitiesChanged;
foreach(LeaderboardEntityState entity in leaderboardEntities)
{
HandleLeaderboardEntitiesChanged(new NetworkListEvent<LeaderboardEntityState>
{
Type = NetworkListEvent<LeaderboardEntityState>.EventType.Add,
Value = entity
}) ;
}
}
if (IsServer)
{
TankPlayer[] players = FindObjectsByType<TankPlayer>(FindObjectsSortMode.None);
foreach (TankPlayer player in players)
{
HandlePlayerSpawned(player);
}
TankPlayer.OnPlayerSpawned += HandlePlayerSpawned;
TankPlayer.OnPlayerDespawned += HandlePlayerDespawned;
}
}
public override void OnNetworkDespawn()
{
if (IsClient)
{
leaderboardEntities.OnListChanged -= HandleLeaderboardEntitiesChanged;
}
if (IsServer)
{
TankPlayer.OnPlayerSpawned -= HandlePlayerSpawned;
TankPlayer.OnPlayerDespawned -= HandlePlayerDespawned;
}
}
private void HandlePlayerSpawned(TankPlayer player)
{
leaderboardEntities.Add( new LeaderboardEntityState
{
ClientId = player.OwnerClientId,
PlayerName = player.PlayerName.Value,
Coins = 0
}
);
player.Wallet.TotalCoin.OnValueChanged += (oldCoins, newCoins) => HandleCoinChanged(player.OwnerClientId, newCoins);
}
private void HandlePlayerDespawned(TankPlayer player)
{
if (leaderboardEntities == null) { return; }
foreach(LeaderboardEntityState entity in leaderboardEntities)
{
if(entity.ClientId != player.OwnerClientId) { continue; }
leaderboardEntities.Remove( entity );
break;
}
player.Wallet.TotalCoin.OnValueChanged -= (oldCoins, newCoins) => HandleCoinChanged(player.OwnerClientId, newCoins);
}
private void HandleLeaderboardEntitiesChanged(NetworkListEvent<LeaderboardEntityState> changeEvent)
{
switch (changeEvent.Type)
{
case NetworkListEvent<LeaderboardEntityState>.EventType.Add:
if (!entitiesDisplays.Any(x => x.ClientId == changeEvent.Value.ClientId))
{
LeaderBoardEntityDisplay leaderboardEntityDisplay = Instantiate(leaderBoardEntityPrefab, leaderBoardEntityHolder);
leaderboardEntityDisplay.Initialise(
changeEvent.Value.ClientId,
changeEvent.Value.PlayerName,
changeEvent.Value.Coins);
entitiesDisplays.Add( leaderboardEntityDisplay );
}
break;
case NetworkListEvent<LeaderboardEntityState>.EventType.Remove:
LeaderBoardEntityDisplay lbed = entitiesDisplays.FirstOrDefault(x => x.ClientId == changeEvent.Value.ClientId);
if (lbed != null)
{
lbed.transform.SetParent(null);
Destroy(lbed.gameObject);
entitiesDisplays.Remove( lbed );
}
break;
case NetworkListEvent<LeaderboardEntityState>.EventType.Value:
LeaderBoardEntityDisplay lbeuPdate = entitiesDisplays.FirstOrDefault(x => x.ClientId == changeEvent.Value.ClientId);
if (lbeuPdate != null)
{
lbeuPdate.UpdateCoins(changeEvent.Value.Coins);
}
break;
}
entitiesDisplays.Sort((x, y) => y.Coins.CompareTo(x.Coins));
for(int i=0;i<entitiesDisplays.Count; i++)
{
entitiesDisplays[i].transform.SetSiblingIndex(i);
entitiesDisplays[i].UpdateText();
bool shouldShow = i <= entitiesToDisplay - 1;
entitiesDisplays[i].gameObject.SetActive(shouldShow);
}
LeaderBoardEntityDisplay myDisplay = entitiesDisplays.FirstOrDefault(x => x.ClientId == NetworkManager.Singleton.LocalClientId);
if(myDisplay != null)
{
if(myDisplay.transform.GetSiblingIndex() > entitiesToDisplay)
{
leaderBoardEntityHolder.GetChild(entitiesToDisplay-1).gameObject.SetActive(false);
myDisplay.gameObject.SetActive(true);
}
}
}
private void HandleCoinChanged(ulong clientId, int newCoins)
{
for(int i = 0; i < leaderboardEntities.Count; i++)
{
if (leaderboardEntities[i].ClientId != clientId) { continue; }
leaderboardEntities[i] = new LeaderboardEntityState
{
ClientId = leaderboardEntities[i].ClientId,
PlayerName = leaderboardEntities[i].PlayerName,
Coins = newCoins
};
return;
}
}
}
Can anyone spot where I go wrong ?
Thanks,