killapp/Assets/Scripts/UI/Components/VerificationCodeInput.cs

278 lines
7.4 KiB
C#
Raw Permalink Normal View History

2026-04-16 14:57:19 +08:00
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Kill.UI.Components
{
/// <summary>
/// 验证码输入组件
/// 使用方式:
/// 1. 在场景中创建一个空物体,挂载此脚本
/// 2. 创建n个Text作为验证码显示位
/// 3. 创建一个InputField作为隐藏输入框可设置为透明或移出屏幕外
/// 4. 在Inspector中配置digitTexts和inputField
/// </summary>
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<string> OnCodeCompleted;
public event Action<string> 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();
}
/// <summary>
/// 初始化组件
/// </summary>
private void Initialize()
{
if (inputField == null)
{
inputField = GetComponentInChildren<InputField>();
}
if (digitTexts == null || digitTexts.Length == 0)
{
digitTexts = GetComponentsInChildren<Text>();
}
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<Text>();
if (placeholder != null)
{
placeholder.color = new Color(1, 1, 1, 0);
}
}
}
}
/// <summary>
/// 处理输入变化
/// </summary>
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);
}
}
/// <summary>
/// 处理结束编辑(用户按下回车或失去焦点)
/// </summary>
private void HandleEndEdit(string value)
{
if (!autoSubmit && currentCode.Length == codeLength)
{
OnCodeCompleted?.Invoke(currentCode);
}
}
/// <summary>
/// 刷新显示
/// </summary>
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;
}
}
}
/// <summary>
/// 过滤非数字字符
/// </summary>
private string FilterNumeric(string input)
{
var result = "";
foreach (char c in input)
{
if (char.IsDigit(c))
{
result += c;
}
}
return result;
}
/// <summary>
/// 获取当前验证码
/// </summary>
public string GetCode()
{
return currentCode;
}
/// <summary>
/// 设置验证码(用于自动填充等)
/// </summary>
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);
}
}
/// <summary>
/// 清空输入
/// </summary>
public void Clear()
{
currentCode = "";
if (inputField != null)
{
inputField.text = "";
}
RefreshDisplay();
}
/// <summary>
/// 让输入框获得焦点
/// </summary>
public void Focus()
{
if (inputField != null)
{
inputField.ActivateInputField();
}
}
/// <summary>
/// 检查验证码是否输入完整
/// </summary>
public bool IsComplete()
{
return currentCode.Length == codeLength;
}
}
}