internal void SendUpdate(bool isInitial)
        {
            if (!CanSync())
            {
                Logging.LogError(LogTag, "Error while set value, behaviour is empty");
                return;
            }
            LiteNetLibGameManager manager = Manager;
            LiteNetLibServer      server  = manager.Server;
            LiteNetLibClient      client  = manager.Client;

            switch (syncMode)
            {
            case SyncMode.ServerToClients:
                TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField);
                SerializeForSend(ServerWriter);
                foreach (long connectionId in manager.GetConnectionIds())
                {
                    if (Identity.HasSubscriberOrIsOwning(connectionId))
                    {
                        server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter);
                    }
                }
                break;

            case SyncMode.ServerToOwnerClient:
                if (manager.ContainsConnectionId(ConnectionId))
                {
                    TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField);
                    SerializeForSend(ServerWriter);
                    server.SendMessage(ConnectionId, dataChannel, deliveryMethod, ServerWriter);
                }
                break;

            case SyncMode.ClientMulticast:
                if (IsOwnerClient)
                {
                    TransportHandler.WritePacket(ClientWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField);
                    SerializeForSend(ClientWriter);
                    // Client send data to server, then server send to other clients, it should be reliable-ordered
                    client.SendMessage(clientDataChannel, clientDeliveryMethod, ClientWriter);
                }
                else if (IsServer)
                {
                    TransportHandler.WritePacket(ServerWriter, isInitial ? GameMsgTypes.InitialSyncField : GameMsgTypes.UpdateSyncField);
                    SerializeForSend(ServerWriter);
                    foreach (long connectionId in manager.GetConnectionIds())
                    {
                        if (Identity.HasSubscriberOrIsOwning(connectionId))
                        {
                            server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter);
                        }
                    }
                }
                break;
            }
        }
        protected void SendCall(DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId)
        {
            LiteNetLibGameManager manager = Manager;

            if (manager.IsServer)
            {
                switch (receivers)
                {
                case FunctionReceivers.Target:
                    if (Identity.IsSubscribedOrOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId))
                    {
                        // Send function call message from server to target client by target connection Id
                        ServerSendCall(targetConnectionId, deliveryMethod);
                    }
                    break;

                case FunctionReceivers.All:
                    foreach (long connectionId in manager.GetConnectionIds())
                    {
                        if (Manager.ClientConnectionId == connectionId)
                        {
                            // This is host's networking oject, so hook callback immediately
                            // Don't have to send message to the client, because it is currently run as both server and client
                            HookCallback();
                        }
                        else if (Identity.IsSubscribedOrOwning(connectionId))
                        {
                            // Send message to subscribing clients
                            ServerSendCall(connectionId, deliveryMethod);
                        }
                    }
                    if (!Manager.IsClientConnected)
                    {
                        // It's not a host(client+host), it's just a server
                        // So hook callback immediately to do the function at server
                        HookCallback();
                    }
                    break;

                case FunctionReceivers.Server:
                    // Call server function at server
                    // So hook callback immediately to do the function at server
                    HookCallback();
                    break;
                }
            }
            else if (manager.IsClientConnected)
            {
                // Client send net function call to server
                // Then the server will hook callback or forward message to other clients
                ClientSendCall(deliveryMethod, receivers, targetConnectionId);
            }
        }
        protected void SendCall(DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId)
        {
            LiteNetLibGameManager manager = Manager;

            if (manager.IsServer)
            {
                switch (receivers)
                {
                case FunctionReceivers.Target:
                    if (Identity.IsSubscribedOrOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId))
                    {
                        ServerSendCall(targetConnectionId, deliveryMethod, receivers, targetConnectionId);
                    }
                    break;

                case FunctionReceivers.All:
                    foreach (long connectionId in manager.GetConnectionIds())
                    {
                        if (Identity.IsSubscribedOrOwning(connectionId))
                        {
                            ServerSendCall(connectionId, deliveryMethod, receivers, targetConnectionId);
                        }
                    }
                    if (!Manager.IsClientConnected)
                    {
                        HookCallback();
                    }
                    break;

                case FunctionReceivers.Server:
                    HookCallback();
                    break;
                }
            }
            else if (manager.IsClientConnected)
            {
                ClientSendCall(deliveryMethod, receivers, targetConnectionId);
            }
        }
        protected void SendCall(byte dataChannel, DeliveryMethod deliveryMethod, FunctionReceivers receivers, long targetConnectionId)
        {
            LiteNetLibGameManager manager = Manager;
            LiteNetLibServer      server  = manager.Server;
            LiteNetLibClient      client  = manager.Client;

            if (manager.IsServer)
            {
                switch (receivers)
                {
                case FunctionReceivers.Target:
                    if (Identity.HasSubscriberOrIsOwning(targetConnectionId) && manager.ContainsConnectionId(targetConnectionId))
                    {
                        // Prepare packet
                        TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction);
                        SerializeForSend(ServerWriter);
                        // Send function call message from server to target client by target connection Id
                        server.SendMessage(targetConnectionId, dataChannel, deliveryMethod, ServerWriter);
                    }
                    break;

                case FunctionReceivers.All:
                    // Send to all connections
                    foreach (long connectionId in manager.GetConnectionIds())
                    {
                        if (manager.ClientConnectionId == connectionId)
                        {
                            // This is host's networking oject, so hook callback immediately
                            // Don't have to send message to the client, because it is currently run as both server and client
                            HookCallback();
                        }
                        else if (Identity.HasSubscriberOrIsOwning(connectionId))
                        {
                            // Prepare packet
                            TransportHandler.WritePacket(ServerWriter, GameMsgTypes.CallFunction);
                            SerializeForSend(ServerWriter);
                            // Send message to subscribing clients
                            server.SendMessage(connectionId, dataChannel, deliveryMethod, ServerWriter);
                        }
                    }
                    if (!manager.IsClientConnected)
                    {
                        // It's not a host(client+host), it's just a server
                        // So hook callback immediately to do the function at server
                        HookCallback();
                    }
                    break;

                case FunctionReceivers.Server:
                    // Call server function at server
                    // So hook callback immediately to do the function at server
                    HookCallback();
                    break;
                }
            }
            else if (manager.IsClientConnected)
            {
                // Prepare packet
                TransportHandler.WritePacket(ClientWriter, GameMsgTypes.CallFunction);
                SerializeForClientSend(ClientWriter, receivers, targetConnectionId);
                // Client send net function call to server
                // Then the server will hook callback or forward message to other clients
                client.SendMessage(dataChannel, deliveryMethod, ClientWriter);
            }
        }