using System; using UnityEngine; using UnityEngine.UI; namespace Kill.UI.Components { /// /// 验证码输入组件 /// 使用方式: /// 1. 在场景中创建一个空物体,挂载此脚本 /// 2. 创建n个Text作为验证码显示位 /// 3. 创建一个InputField作为隐藏输入框(可设置为透明或移出屏幕外) /// 4. 在Inspector中配置digitTexts和inputField /// public class VerificationCodeInput : MonoBehaviour { [Header("验证码配置")] [Tooltip("验证码位数")] [Range(1, 10)] public int codeLength = 6; [Tooltip("是否自动验证 - 输入完成后自动触发OnCodeCompleted事件")] public bool autoSubmit = true; [Tooltip("是否只允许数字")] public bool numericOnly = true; [Header("UI引用")] [Tooltip("验证码显示文本数组,按顺序从左到右")] public Text[] digitTexts; [Tooltip("隐藏的输入框(用于接收用户输入)")] public InputField inputField; [Header("样式配置")] [Tooltip("未输入时的占位字符")] public string placeholderChar = "-"; [Tooltip("输入完成后的字符(如需要隐藏可设为*)")] public string displayChar = ""; public event Action OnCodeCompleted; public event Action OnCodeChanged; private string currentCode = ""; private void Awake() { Initialize(); } private void OnEnable() { if (inputField != null) { inputField.onValueChanged.AddListener(HandleInputChanged); inputField.onEndEdit.AddListener(HandleEndEdit); } } private void OnDisable() { if (inputField != null) { inputField.onValueChanged.RemoveListener(HandleInputChanged); inputField.onEndEdit.RemoveListener(HandleEndEdit); } } private void Start() { RefreshDisplay(); } /// /// 初始化组件 /// private void Initialize() { if (inputField == null) { inputField = GetComponentInChildren(); } if (digitTexts == null || digitTexts.Length == 0) { digitTexts = GetComponentsInChildren(); } if (digitTexts != null && digitTexts.Length > 0) { codeLength = Mathf.Min(codeLength, digitTexts.Length); } if (inputField != null) { inputField.characterLimit = codeLength; inputField.contentType = numericOnly ? InputField.ContentType.IntegerNumber : InputField.ContentType.Alphanumeric; var inputText = inputField.textComponent; if (inputText != null) { inputText.color = new Color(1, 1, 1, 0); } if (inputField.placeholder != null) { var placeholder = inputField.placeholder.GetComponent(); if (placeholder != null) { placeholder.color = new Color(1, 1, 1, 0); } } } } /// /// 处理输入变化 /// private void HandleInputChanged(string value) { if (numericOnly) { value = FilterNumeric(value); if (inputField != null && inputField.text != value) { inputField.text = value; return; } } if (value.Length > codeLength) { value = value.Substring(0, codeLength); if (inputField != null) { inputField.text = value; return; } } currentCode = value; RefreshDisplay(); OnCodeChanged?.Invoke(currentCode); if (autoSubmit && currentCode.Length == codeLength) { Debug.Log("自动提交"); OnCodeCompleted?.Invoke(currentCode); } } /// /// 处理结束编辑(用户按下回车或失去焦点) /// private void HandleEndEdit(string value) { if (!autoSubmit && currentCode.Length == codeLength) { OnCodeCompleted?.Invoke(currentCode); } } /// /// 刷新显示 /// private void RefreshDisplay() { if (digitTexts == null) return; for (int i = 0; i < digitTexts.Length; i++) { if (digitTexts[i] == null) continue; if (i < currentCode.Length) { char c = currentCode[i]; digitTexts[i].text = string.IsNullOrEmpty(displayChar) ? c.ToString() : displayChar; } else { digitTexts[i].text = placeholderChar; } } } /// /// 过滤非数字字符 /// private string FilterNumeric(string input) { var result = ""; foreach (char c in input) { if (char.IsDigit(c)) { result += c; } } return result; } /// /// 获取当前验证码 /// public string GetCode() { return currentCode; } /// /// 设置验证码(用于自动填充等) /// public void SetCode(string code) { if (code == null) { code = ""; } if (code.Length > codeLength) { code = code.Substring(0, codeLength); } currentCode = code; if (inputField != null) { inputField.text = currentCode; } RefreshDisplay(); OnCodeChanged?.Invoke(currentCode); if (currentCode.Length == codeLength) { OnCodeCompleted?.Invoke(currentCode); } } /// /// 清空输入 /// public void Clear() { currentCode = ""; if (inputField != null) { inputField.text = ""; } RefreshDisplay(); } /// /// 让输入框获得焦点 /// public void Focus() { if (inputField != null) { inputField.ActivateInputField(); } } /// /// 检查验证码是否输入完整 /// public bool IsComplete() { return currentCode.Length == codeLength; } } }