Skip to content

SyncList double items for the third client #913

@busaku

Description

@busaku

General
Unity version: 6000.0.28f1
Fish-Networking version: 4.6.8R

Description
The third (and more) Client got one extra Item in SyncList

Replication
Use this script:

using System;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using UnityEngine;

public class PlayerManager : NetworkBehaviour
{
    public static PlayerManager Instance { get; private set; }

    private readonly SyncList<PlayerStat> players = new();

    public static event Action<SyncList<PlayerStat>> OnPlayersChanged;

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(this);
            return;
        }

        Instance = this;

        players.OnChange += playersChange;
    }

    private void playersChange(SyncListOperation op, int index,
     PlayerStat oldItem, PlayerStat newItem, bool asServer)
    {
        Debug.Log($"[PlayerManager] Player list changed: {op} at index {index} Server: {asServer}");
        //OnPlayersChanged?.Invoke(players);

        // list debug 
        for (int i = 0; i < players.Count; i++)
        {
            Debug.Log($"Player {i}: {players[i].playerName} (ID: {players[i].connectionId})");
        }
    }

    [Server]
    public void RegisterPlayer(int connectionId, string playerName, string characterClass)
    {
        Debug.Log("Test");
        bool alreadyRegistered = false;
        foreach (var p in players)
        {
            if (p.connectionId == connectionId)
            {
                alreadyRegistered = true;
                break;
            }
        }

        if (!alreadyRegistered)
        {
            var playerStat = new PlayerStat
            {
                connectionId = connectionId,
                playerName = playerName,
            };
            players.Add(playerStat);
            Debug.Log($"[PlayerManager] Registered: {playerName} ({connectionId})");
        }
    }

    [Server]
    public void UnregisterPlayer(int connectionId)
    {
        int index = players.FindIndex(p => p.connectionId == connectionId);
        if (index >= 0)
        {
            var removed = players[index];
            Debug.Log($"[PlayerManager] Unregistered: {players[index].playerName} ({connectionId})");
            players.RemoveAt(index);
        }
    }
}

and than call this on you player-Prefab (spawned by FishNet):

    public override void OnStartServer()
    {
        base.OnStartServer();

        if (!IsServerInitialized) return; 

        // Temporärer Dummy-Name
        string name = $"Player_{Owner.ClientId}";
        string klass = "Default";

        PlayerManager.Instance?.RegisterPlayer(Owner.ClientId, name, klass);
    }

Result
All Clients, after the first, got an extra Item inside the SyncList (Copy of her own?).
Means: The Server and the First Client have this list after all clients are joined:

Image

Image

Player 2 got:
(ID 1 = Player2)
Image

And Player 3 got:

Image

I don't have an idea, why the clients just get a copy of the own PlayerStat.
And i don't know why it doesn't happend on the first Client or even the Server?

Thanks in advance :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't workingResolved Pending ReleaseIssue is resolved and will be available on the noted version.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions