private IEnumerator HandleRequestCreateCharacterRoutine(LiteNetLibMessageHandler messageHandler)
        {
            var connectionId  = messageHandler.connectionId;
            var message       = messageHandler.ReadMessage <RequestCreateCharacterMessage>();
            var error         = ResponseCreateCharacterMessage.Error.None;
            var characterName = message.characterName;
            var databaseId    = message.dataId;
            CentralUserPeerInfo userPeerInfo;
            var findCharacterNameJob = new FindCharacterNameJob(Database, characterName);

            findCharacterNameJob.Start();
            yield return(StartCoroutine(findCharacterNameJob.WaitFor()));

            if (findCharacterNameJob.result > 0)
            {
                error = ResponseCreateCharacterMessage.Error.CharacterNameAlreadyExisted;
            }
            else if (!userPeers.TryGetValue(connectionId, out userPeerInfo))
            {
                error = ResponseCreateCharacterMessage.Error.NotLoggedin;
            }
            else if (string.IsNullOrEmpty(characterName) || characterName.Length < minCharacterNameLength)
            {
                error = ResponseCreateCharacterMessage.Error.TooShortCharacterName;
            }
            else if (characterName.Length > maxCharacterNameLength)
            {
                error = ResponseCreateCharacterMessage.Error.TooLongCharacterName;
            }
            else if (!GameInstance.PlayerCharacters.ContainsKey(databaseId))
            {
                error = ResponseCreateCharacterMessage.Error.InvalidData;
            }
            else
            {
                var characterId   = GenericUtils.GetUniqueId();
                var characterData = new PlayerCharacterData();
                characterData.Id = characterId;
                characterData.SetNewCharacterData(characterName, databaseId);
                var createCharacterJob = new CreateCharacterJob(Database, userPeerInfo.userId, characterData);
                createCharacterJob.Start();
                yield return(StartCoroutine(createCharacterJob.WaitFor()));
            }
            var responseMessage = new ResponseCreateCharacterMessage();

            responseMessage.ackId        = message.ackId;
            responseMessage.responseCode = error == ResponseCreateCharacterMessage.Error.None ? AckResponseCode.Success : AckResponseCode.Error;
            responseMessage.error        = error;
            ServerSendPacket(connectionId, SendOptions.ReliableOrdered, MMOMessageTypes.ResponseCreateCharacter, responseMessage);
        }
    private void OnClickCreate()
    {
        var gameInstance = GameInstance.Singleton;
        var selectedUI   = SelectionManager.SelectedUI;

        if (selectedUI == null)
        {
            UISceneGlobal.Singleton.ShowMessageDialog("Cannot create character", "Please select character class");
            Debug.LogWarning("Cannot create character, did not selected character class");
            return;
        }
        var dataId                 = selectedUI.dataId;
        var characterName          = inputCharacterName.text.Trim();
        var minCharacterNameLength = gameInstance.minCharacterNameLength;
        var maxCharacterNameLength = gameInstance.maxCharacterNameLength;

        if (characterName.Length < minCharacterNameLength)
        {
            UISceneGlobal.Singleton.ShowMessageDialog("Cannot create character", "Character name is too short");
            Debug.LogWarning("Cannot create character, character name is too short");
            return;
        }
        if (characterName.Length > maxCharacterNameLength)
        {
            UISceneGlobal.Singleton.ShowMessageDialog("Cannot create character", "Character name is too long");
            Debug.LogWarning("Cannot create character, character name is too long");
            return;
        }

        var characterId   = GenericUtils.GetUniqueId();
        var characterData = new PlayerCharacterData();

        characterData.Id = characterId;
        characterData.SetNewCharacterData(characterName, dataId);
        characterData.SavePersistentCharacterData();

        if (eventOnCreateCharacter != null)
        {
            eventOnCreateCharacter.Invoke();
        }
    }
    private void LoadCharacters()
    {
        SelectionManager.Clear();
        // Show list of characters that can be create
        var selectableCharacters = GameInstance.PlayerCharacters.Values.ToList();

        CacheList.Generate(selectableCharacters, (index, character, ui) =>
        {
            var dataId           = character.HashId;
            var characterData    = new PlayerCharacterData();
            characterData.DataId = dataId;
            characterData.SetNewCharacterData(character.title, character.HashId);
            var uiCharacter = ui.GetComponent <UICharacter>();
            uiCharacter.Setup(characterData, dataId);
            // Select trigger when add first entry so deactivate all models is okay beacause first model will active
            var characterModel = characterData.InstantiateModel(characterModelContainer);
            CharacterModels[characterData.dataId] = characterModel;
            characterModel.gameObject.SetActive(false);
            SelectionManager.Add(uiCharacter);
        });
    }