Hello everybody,
So this problem appeared probably a while ago, but i noticed it now. so if the first build with name (Build1) kills the second build (build2), then build2 will become build1 and now there is two build1s in the game (overhead names change too) i dont know what script is related to this issue but here is some scripts:
Leaderboard
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Netcode;
using UnityEngine;
public class Leaderboard : NetworkBehaviour
{
[SerializeField] private Transform leaderboardEntityHolder;
[SerializeField] private LeaderboardEntityDisplay leaderboardEntityPrefab;
[SerializeField] private int entitiesToDisplay = 8;
private NetworkList<LeaderboardEntityState> leaderboardEntities;
private List<LeaderboardEntityDisplay> entityDisplays = 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 HandleLeaderboardEntitiesChanged(NetworkListEvent<LeaderboardEntityState> changeEvent)
{
switch (changeEvent.Type)
{
case NetworkListEvent<LeaderboardEntityState>.EventType.Add:
if (!entityDisplays.Any(x => x.ClientId == changeEvent.Value.ClientId))
{
LeaderboardEntityDisplay leaderboardEntity =
Instantiate(leaderboardEntityPrefab, leaderboardEntityHolder);
leaderboardEntity.Initialise(
changeEvent.Value.ClientId,
changeEvent.Value.PlayerName,
changeEvent.Value.Coins);
entityDisplays.Add(leaderboardEntity);
}
break;
case NetworkListEvent<LeaderboardEntityState>.EventType.Remove:
LeaderboardEntityDisplay displayToRemove =
entityDisplays.FirstOrDefault(x => x.ClientId == changeEvent.Value.ClientId);
if (displayToRemove != null)
{
displayToRemove.transform.SetParent(null);
Destroy(displayToRemove.gameObject);
entityDisplays.Remove(displayToRemove);
}
break;
case NetworkListEvent<LeaderboardEntityState>.EventType.Value:
LeaderboardEntityDisplay displayToUpdate =
entityDisplays.FirstOrDefault(x => x.ClientId == changeEvent.Value.ClientId);
if (displayToUpdate != null)
{
displayToUpdate.UpdateCoins(changeEvent.Value.Coins);
}
break;
}
entityDisplays.Sort((x, y) => y.Coins.CompareTo(x.Coins));
for (int i = 0; i < entityDisplays.Count; i++)
{
entityDisplays[i].transform.SetSiblingIndex(i);
entityDisplays[i].UpdateText();
entityDisplays[i].gameObject.SetActive(i <= entitiesToDisplay - 1);
}
LeaderboardEntityDisplay myDisplay =
entityDisplays.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 HandlePlayerSpawned(TankPlayer player)
{
leaderboardEntities.Add(new LeaderboardEntityState
{
ClientId = player.OwnerClientId,
PlayerName = player.PlayerName.Value,
Coins = 0
});
player.Wallet.TotalCoins.OnValueChanged += (oldCoins, newCoins) =>
HandleCoinsChanged(player.OwnerClientId, newCoins);
}
private void HandlePlayerDespawned(TankPlayer player)
{
foreach (LeaderboardEntityState entity in leaderboardEntities)
{
if (entity.ClientId != player.OwnerClientId) { continue; }
leaderboardEntities.Remove(entity);
break;
}
player.Wallet.TotalCoins.OnValueChanged -= (oldCoins, newCoins) =>
HandleCoinsChanged(player.OwnerClientId, newCoins);
}
private void HandleCoinsChanged(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;
}
}
}
LeaderboardEntityDisplay
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
public class LeaderboardEntityDisplay : MonoBehaviour
{
[SerializeField] private Color myNameColor;
[SerializeField] private Color topOneColor;
[SerializeField] private Color topTwoColor;
[SerializeField] private Color topThreeColor;
[SerializeField] private Color otherTopColor;
[SerializeField] private TMP_Text playerNameText;
[SerializeField] private TMP_Text placeText;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private Image placeBackground;
private FixedString32Bytes playerName;
public ulong ClientId { get; private set; }
public int Coins { get; private set; }
public void Initialise(ulong clientId, FixedString32Bytes playerName, int coins)
{
ClientId = clientId;
this.playerName = playerName;
if (clientId == NetworkManager.Singleton.LocalClientId)
{
playerNameText.color = myNameColor;
}
UpdateCoins(coins);
}
public void UpdateText()
{
if (transform.GetSiblingIndex() + 1 == 1)
{
placeBackground.color = topOneColor;
}
else if (transform.GetSiblingIndex() + 1 == 2)
{
placeBackground.color = topTwoColor;
}
else if (transform.GetSiblingIndex() + 1 == 3)
{
placeBackground.color = topThreeColor;
}
else
{
placeBackground.color = otherTopColor;
}
placeText.text = (transform.GetSiblingIndex() + 1).ToString();
playerNameText.text = playerName.ToString();
scoreText.text = Coins.ToString();
}
public void UpdateCoins(int coins)
{
Coins = coins;
UpdateText();
}
}
RespawnHandle (because its related to death)
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
public class RespawnHandler : NetworkBehaviour
{
[SerializeField] private NetworkObject playerPrefab;
public override void OnNetworkSpawn()
{
if (!IsServer) { return; }
TankPlayer[] players = FindObjectsOfType<TankPlayer>();
foreach (TankPlayer player in players)
{
HandlePlayerSpawned(player);
}
TankPlayer.OnPlayerSpawned += HandlePlayerSpawned;
TankPlayer.OnPlayerDespawned += HandlePlayerDespawned;
}
public override void OnNetworkDespawn()
{
if (!IsServer) { return; }
TankPlayer.OnPlayerSpawned -= HandlePlayerSpawned;
TankPlayer.OnPlayerDespawned -= HandlePlayerDespawned;
}
private void HandlePlayerSpawned(TankPlayer player)
{
player.Health.OnDie += (health) => HandlePlayerDie(player);
}
private void HandlePlayerDespawned(TankPlayer player)
{
player.Health.OnDie -= (health) => HandlePlayerDie(player);
}
private void HandlePlayerDie(TankPlayer player)
{
Destroy(player.gameObject);
StartCoroutine(RespawnPlayer(player.OwnerClientId));
}
private IEnumerator RespawnPlayer(ulong ownerClientId)
{
yield return null;
NetworkObject playerInstance = Instantiate(
playerPrefab, SpawnPoint.GetRandomSpawnPos(), Quaternion.identity);
playerInstance.SpawnAsPlayerObject(ownerClientId);
}
}
Health
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
public class Health : NetworkBehaviour
{
[field: SerializeField] public int MaxHealth { get; private set; } = 100;
public NetworkVariable<int> CurrentHealth = new NetworkVariable<int>();
private bool isDead;
public Action<Health> OnDie;
public override void OnNetworkSpawn()
{
if (!IsServer) { return; }
CurrentHealth.Value = MaxHealth;
}
public void TakeDamage(int damageValue)
{
ModifyHealth(-damageValue);
}
public void RestoreHealth(int healValue)
{
ModifyHealth(healValue);
}
private void ModifyHealth(int value)
{
if (isDead) { return; }
int newHealth = CurrentHealth.Value + value;
CurrentHealth.Value = Mathf.Clamp(newHealth, 0, MaxHealth);
if(CurrentHealth.Value == 0)
{
OnDie?.Invoke(this);
isDead = true;
}
}
}
TankPlayer
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
using Cinemachine;
using Unity.Collections;
using System;
public class TankPlayer : NetworkBehaviour
{
[Header("References")]
[SerializeField] private CinemachineVirtualCamera virtualCamera;
[field: SerializeField] public Health Health { get; private set; }
[field: SerializeField] public CoinWallet Wallet { get; private set; }
[Header("Settings")]
[SerializeField] private int ownerPriority = 15;
public NetworkVariable<FixedString32Bytes> PlayerName = new NetworkVariable<FixedString32Bytes>();
public static event Action<TankPlayer> OnPlayerSpawned;
public static event Action<TankPlayer> OnPlayerDespawned;
public override void OnNetworkSpawn()
{
if (IsServer)
{
UserData userData =
HostSingleton.Instance.GameManager.NetworkServer.GetUserDataByClientId(OwnerClientId);
PlayerName.Value = userData.userName;
OnPlayerSpawned?.Invoke(this);
}
if (IsOwner)
{
virtualCamera.Priority = ownerPriority;
}
}
public override void OnNetworkDespawn()
{
if (IsServer)
{
OnPlayerDespawned?.Invoke(this);
}
}
}
If you need any other script tell me, please help.