源代码详情

返回代码列表
C++

USB-HID刷卡感应切换场景

作者: 超级管理员 发布时间: 2025-12-31 16:03 下载次数: 6 最后更新: 2026-01-04 08:37
CardSceneManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Collections;
using System.Text;
using System.IO;

public class CardSceneManager : MonoBehaviour
{
    // 序列化字段,可在Inspector中配置
    [Header("刷卡器配置")]
    [Tooltip("数据接收的最大长度")]
    [SerializeField] private int maxInputLength = 20;
    
    [Tooltip("清除输入的延迟时间(秒)")]
    [SerializeField] private float clearInputDelay = 2f;
    
    [Header("场景映射配置")]
    [Tooltip("卡号与场景名称的映射关系")]
    [SerializeField] private CardSceneMapping[] cardSceneMappings;
    
    // 私有变量
    private StringBuilder cardInput = new StringBuilder();
    private bool isReceivingInput = false;
    private Coroutine clearInputCoroutine;
    
    // 卡号场景映射结构
    [System.Serializable]
    public struct CardSceneMapping
    {
        public string cardNumber;   // 卡号
        public string sceneName;    // 对应场景名称
    }
    
    // 单例模式
    public static CardSceneManager Instance { get; private set; }
    
    void Awake()
    {
        // 单例初始化
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    void Start()
    {
        // 初始化映射表(如果没有在Inspector中配置)
        if (cardSceneMappings == null || cardSceneMappings.Length == 0)
        {
            InitializeDefaultMappings();
        }
        
        Debug.Log("刷卡器监听已启动...");
    }
    
    void InitializeDefaultMappings()
    {
        // 默认映射关系
        cardSceneMappings = new CardSceneMapping[]
        {
            new CardSceneMapping { cardNumber = "0000000001", sceneName = "001" },
            new CardSceneMapping { cardNumber = "0000000002", sceneName = "002" },
            new CardSceneMapping { cardNumber = "0000000003", sceneName = "003" },
            new CardSceneMapping { cardNumber = "0000000004", sceneName = "004" },
            new CardSceneMapping { cardNumber = "0000000005", sceneName = "005" }
        };
    }
    
    void Update()
    {
        // 监听键盘输入
        ProcessKeyboardInput();
    }
    
    void ProcessKeyboardInput()
    {
        // 获取当前帧的所有输入字符
        string input = Input.inputString;
        
        if (!string.IsNullOrEmpty(input))
        {
            // 开始接收输入
            isReceivingInput = true;
            
            // 重置清除计时器
            if (clearInputCoroutine != null)
            {
                StopCoroutine(clearInputCoroutine);
            }
            
            // 处理每个字符
            foreach (char c in input)
            {
                ProcessCharacter(c);
            }
            
            // 启动新的清除计时器
            clearInputCoroutine = StartCoroutine(ClearInputAfterDelay());
        }
    }
    
    void ProcessCharacter(char c)
    {
        // 检测回车键(\r 或 \n)
        if (c == '\r' || c == '\n')
        {
            if (cardInput.Length > 0)
            {
                string cardNumber = cardInput.ToString();
                Debug.Log($"收到卡号: {cardNumber}");
                
                // 处理卡号
                HandleCardNumber(cardNumber);
                
                // 清空当前输入
                cardInput.Clear();
            }
            return;
        }
        
        // 只接受数字字符
        if (char.IsDigit(c))
        {
            if (cardInput.Length < maxInputLength)
            {
                cardInput.Append(c);
                Debug.Log($"当前输入: {cardInput.ToString()}");
            }
            else
            {
                Debug.LogWarning($"输入超过最大长度 {maxInputLength},已忽略");
            }
        }
        else
        {
            Debug.LogWarning($"检测到非数字字符: {c},已忽略");
        }
    }
    
    void HandleCardNumber(string cardNumber)
    {
        // 去除可能的前导零,但保留至少一位
        string processedCardNumber = cardNumber.TrimStart('0');
        if (string.IsNullOrEmpty(processedCardNumber))
        {
            processedCardNumber = "0";
        }
        
        Debug.Log($"处理后的卡号: {processedCardNumber}");
        
        // 查找对应的场景
        string sceneName = FindSceneForCard(cardNumber, processedCardNumber);
        
        if (!string.IsNullOrEmpty(sceneName))
        {
            LoadScene(sceneName);
        }
        else
        {
            Debug.LogWarning($"未找到卡号 {cardNumber} 对应的场景映射");
            // 可以在这里播放错误提示音或显示提示
        }
    }
    
    string FindSceneForCard(string originalCardNumber, string processedCardNumber)
    {
        // 优先使用原始卡号查找
        foreach (var mapping in cardSceneMappings)
        {
            if (mapping.cardNumber == originalCardNumber)
            {
                return mapping.sceneName;
            }
        }
        
        // 如果原始卡号没找到,使用处理后的卡号查找
        foreach (var mapping in cardSceneMappings)
        {
            // 移除映射卡号的前导零
            string processedMapping = mapping.cardNumber.TrimStart('0');
            if (string.IsNullOrEmpty(processedMapping))
            {
                processedMapping = "0";
            }
            
            if (processedMapping == processedCardNumber)
            {
                return mapping.sceneName;
            }
        }
        
        return null;
    }
    
    void LoadScene(string sceneName)
    {
        try
        {
            // 检查场景是否存在
            if (SceneExists(sceneName))
            {
                Debug.Log($"切换到场景: {sceneName}");
                SceneManager.LoadScene(sceneName);
            }
            else
            {
                Debug.LogError($"场景 {sceneName} 不存在!请检查Build Settings");
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"加载场景时出错: {e.Message}");
        }
    }
    
    bool SceneExists(string sceneName)
    {
        // 检查场景是否在Build Settings中
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
            string sceneNameInBuild = Path.GetFileNameWithoutExtension(scenePath);
            
            if (sceneNameInBuild == sceneName)
            {
                return true;
            }
        }
        return false;
    }
    
    IEnumerator ClearInputAfterDelay()
    {
        yield return new WaitForSeconds(clearInputDelay);
        
        if (cardInput.Length > 0)
        {
            Debug.Log($"输入超时,清除未完成的输入: {cardInput.ToString()}");
            cardInput.Clear();
        }
        
        isReceivingInput = false;
        clearInputCoroutine = null;
    }
    
    // 公共方法:手动添加卡号(用于测试)
    public void SimulateCardSwipe(string cardNumber)
    {
        if (!string.IsNullOrEmpty(cardNumber))
        {
            HandleCardNumber(cardNumber);
        }
    }
    
    // 公共方法:获取当前输入状态
    public string GetCurrentInput()
    {
        return cardInput.ToString();
    }
    
    // 公共方法:清空当前输入
    public void ClearCurrentInput()
    {
        cardInput.Clear();
        Debug.Log("已清空当前输入");
    }
    
    void OnGUI()
    {
        // 显示当前输入状态(仅用于调试)
        if (isReceivingInput && cardInput.Length > 0)
        {
            GUI.Box(new Rect(10, 10, 200, 25), "刷卡输入中...");
            GUI.Label(new Rect(10, 40, 300, 25), $"当前卡号: {cardInput.ToString()}");
        }
    }
}