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;
}
}
}