diff --git a/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs
new file mode 100644
index 0000000000..c8af5d8047
--- /dev/null
+++ b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs
@@ -0,0 +1,217 @@
+using System;
+using System.Text;
+using BrewMonster.Network;
+using CSNetwork;
+using CSNetwork.GPDataType;
+using CSNetwork.Protocols;
+using CSNetwork.Protocols.RPCData;
+using TMPro;
+using UnityEngine;
+using UnityEngine.UI;
+using BrewMonster.Scripts;
+
+namespace BrewMonster.UI
+{
+ ///
+ /// UI screen for creating a new character.
+ /// Equivalent to CDlgCreateGenderName + CDlgCreateProfession in C++.
+ ///
+ public class CreateCharacterScreen : MonoBehaviour
+ {
+ [SerializeField] private GameObject professionSelectionPanel;
+ [SerializeField] private Button[] professionButtons;
+ [SerializeField] private Button maleGenderButton;
+ [SerializeField] private Button femaleGenderButton;
+ [SerializeField] private TMP_InputField nameInputField;
+ [SerializeField] private Button confirmButton;
+ [SerializeField] private Button cancelButton;
+ [SerializeField] private Button backButton;
+
+ private int _currentProfession = -1;
+ private int _currentGender = -1;
+
+ private Action _onCreateComplete;
+ private Action _onCancel;
+
+ private void Start()
+ {
+ if (confirmButton != null)
+ confirmButton.onClick.AddListener(OnConfirmClicked);
+ if (cancelButton != null)
+ cancelButton.onClick.AddListener(OnCancelClicked);
+ if (backButton != null)
+ backButton.onClick.AddListener(OnCancelClicked);
+
+ if (maleGenderButton != null)
+ maleGenderButton.onClick.AddListener(() => OnGenderSelected(GENDER.GENDER_MALE));
+ if (femaleGenderButton != null)
+ femaleGenderButton.onClick.AddListener(() => OnGenderSelected(GENDER.GENDER_FEMALE));
+
+ // Setup profession buttons
+ if (professionButtons != null)
+ {
+ for (int i = 0; i < professionButtons.Length && i < 12; i++)
+ {
+ int prof = i; // Capture for closure
+ if (professionButtons[i] != null)
+ professionButtons[i].onClick.AddListener(() => OnProfessionSelected(prof));
+ }
+ }
+
+ if (nameInputField != null)
+ {
+ nameInputField.onSubmit.AddListener((text) => { if (CanConfirm()) OnConfirmClicked(); });
+ }
+ }
+
+ public void Show(Action onCreateComplete, Action onCancel)
+ {
+ _onCreateComplete = onCreateComplete;
+ _onCancel = onCancel;
+ _currentProfession = -1;
+ _currentGender = -1;
+
+ gameObject.SetActive(true);
+
+ if (nameInputField != null)
+ {
+ nameInputField.text = "";
+ nameInputField.Select();
+ }
+
+ UpdateConfirmButtonState();
+ }
+
+ public void Hide()
+ {
+ gameObject.SetActive(false);
+ }
+
+ private void OnProfessionSelected(int profession)
+ {
+ if (profession < 0 || profession >= (int)Profession.NUM_PROFESSION)
+ return;
+
+ _currentProfession = profession;
+
+ // Update UI to show selected profession
+ if (professionButtons != null)
+ {
+ for (int i = 0; i < professionButtons.Length; i++)
+ {
+ if (professionButtons[i] != null)
+ {
+ // Visual feedback for selected profession
+ var colors = professionButtons[i].colors;
+ colors.normalColor = (i == profession) ? Color.yellow : Color.white;
+ professionButtons[i].colors = colors;
+ }
+ }
+ }
+
+ // Auto-select first available gender for this profession if not selected
+ if (_currentGender == -1)
+ {
+ // Default to male if available, otherwise female
+ OnGenderSelected(GENDER.GENDER_MALE);
+ }
+
+ UpdateConfirmButtonState();
+ }
+
+ private void OnGenderSelected(int gender)
+ {
+ if (gender != GENDER.GENDER_MALE && gender != GENDER.GENDER_FEMALE)
+ return;
+
+ _currentGender = gender;
+
+ // Update UI to show selected gender
+ if (maleGenderButton != null)
+ {
+ var colors = maleGenderButton.colors;
+ colors.normalColor = (gender == GENDER.GENDER_MALE) ? Color.yellow : Color.white;
+ maleGenderButton.colors = colors;
+ }
+
+ if (femaleGenderButton != null)
+ {
+ var colors = femaleGenderButton.colors;
+ colors.normalColor = (gender == GENDER.GENDER_FEMALE) ? Color.yellow : Color.white;
+ femaleGenderButton.colors = colors;
+ }
+
+ UpdateConfirmButtonState();
+ }
+
+ private void OnConfirmClicked()
+ {
+ if (!CanConfirm())
+ return;
+
+ string characterName = nameInputField != null ? nameInputField.text : "";
+ if (string.IsNullOrWhiteSpace(characterName))
+ {
+ Debug.LogWarning("Character name cannot be empty");
+ return;
+ }
+
+ // Create RoleInfo using helper method
+ RoleInfo roleInfo = GameSession.CreateNewRoleInfo(characterName, _currentProfession, _currentGender);
+
+ // Create role via network
+ Debug.Log($"Calling CreateRoleAsync for character: {characterName}, profession: {_currentProfession}, gender: {_currentGender}");
+ UnityGameSession.CreateRoleAsync(roleInfo, new Octets(), (createdRole) =>
+ {
+ if (createdRole != null)
+ {
+ Debug.Log($"Character created successfully: {characterName}, RoleID: {createdRole.roleid}");
+ _onCreateComplete?.Invoke(createdRole);
+ }
+ else
+ {
+ Debug.LogError($"Failed to create character: {characterName}. Check GameSession logs for error details.");
+ // TODO: Show error message to user
+ }
+ });
+ }
+
+ private void OnCancelClicked()
+ {
+ Hide();
+ _onCancel?.Invoke();
+ }
+
+ private bool CanConfirm()
+ {
+ if (_currentProfession < 0 || _currentProfession >= (int)Profession.NUM_PROFESSION)
+ return false;
+
+ if (_currentGender != GENDER.GENDER_MALE && _currentGender != GENDER.GENDER_FEMALE)
+ return false;
+
+ string name = nameInputField != null ? nameInputField.text : "";
+ if (string.IsNullOrWhiteSpace(name))
+ return false;
+
+ return true;
+ }
+
+ private void UpdateConfirmButtonState()
+ {
+ if (confirmButton != null)
+ {
+ confirmButton.interactable = CanConfirm();
+ }
+ }
+
+ private void Update()
+ {
+ // Update confirm button state in case name changes
+ if (nameInputField != null && nameInputField.isFocused)
+ {
+ UpdateConfirmButtonState();
+ }
+ }
+ }
+}
diff --git a/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta
new file mode 100644
index 0000000000..5a22e1e624
--- /dev/null
+++ b/Assets/PerfectWorld/Scripts/UI/Login/CreateCharacterScreen.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: aa9de023137e92348983cee3c59d620b
\ No newline at end of file
diff --git a/Assets/Scripts/SelecScreenCharacter.cs b/Assets/Scripts/SelecScreenCharacter.cs
index 087b6a401a..bdcf91c5a2 100644
--- a/Assets/Scripts/SelecScreenCharacter.cs
+++ b/Assets/Scripts/SelecScreenCharacter.cs
@@ -2,6 +2,7 @@ using CSNetwork.Protocols.RPCData;
using System;
using System.Collections.Generic;
using UnityEngine;
+using UnityEngine.UI;
using BrewMonster;
namespace BrewMonster.UI
@@ -10,15 +11,76 @@ namespace BrewMonster.UI
{
[SerializeField] private GameObject characterItemPrefab;
[SerializeField] private RectTransform parentItems;
+ [SerializeField] private Button createCharacterButton;
+ [SerializeField] private CreateCharacterScreen createCharacterScreen;
- public void InitScreen(List roleInfos, Action OnClickItemChar)
+ private Action _onClickItemChar;
+ private Action _onCreateCharacterComplete;
+
+ private void Start()
{
-
- foreach (RoleInfo info in roleInfos)
+ if (createCharacterButton != null)
{
- CharacterItemUI item = Instantiate(characterItemPrefab, parentItems).GetComponent();
- item.InitItem(info, OnClickItemChar);
+ createCharacterButton.onClick.AddListener(OnCreateCharacterClicked);
}
}
+
+ public void InitScreen(List roleInfos, Action OnClickItemChar, Action onCreateCharacterComplete = null)
+ {
+ _onClickItemChar = OnClickItemChar;
+ _onCreateCharacterComplete = onCreateCharacterComplete;
+
+ // Clear existing items
+ if (parentItems != null)
+ {
+ foreach (Transform child in parentItems)
+ {
+ Destroy(child.gameObject);
+ }
+ }
+
+ // Create character items
+ if (roleInfos != null)
+ {
+ foreach (RoleInfo info in roleInfos)
+ {
+ if (characterItemPrefab != null && parentItems != null)
+ {
+ CharacterItemUI item = Instantiate(characterItemPrefab, parentItems).GetComponent();
+ item.InitItem(info, OnClickItemChar);
+ }
+ }
+ }
+ }
+
+ private void OnCreateCharacterClicked()
+ {
+ if (createCharacterScreen != null)
+ {
+ gameObject.SetActive(false);
+ createCharacterScreen.Show(OnCreateCharacterComplete, OnCreateCharacterCancel);
+ }
+ }
+
+ private void OnCreateCharacterComplete(RoleInfo newRole)
+ {
+ if (createCharacterScreen != null)
+ {
+ createCharacterScreen.Hide();
+ }
+
+ gameObject.SetActive(true);
+ _onCreateCharacterComplete?.Invoke();
+ }
+
+ private void OnCreateCharacterCancel()
+ {
+ if (createCharacterScreen != null)
+ {
+ createCharacterScreen.Hide();
+ }
+
+ gameObject.SetActive(true);
+ }
}
}