DCS/ruiyiweiUX/Assets/Scripts/UI/Dialogs/PinyinInputManager.cs

337 lines
16 KiB
C#
Raw Permalink Normal View History

2026-06-09 13:59:11 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
/// <summary>
/// 拼音输入管理器 - 将拼音转换为候选汉字
/// 支持从 StreamingAssets 加载完整拼音词库
/// </summary>
public class PinyinInputManager
{
// 拼音到汉字的映射表
private static Dictionary<string, string[]> PinyinDict = null;
private static bool _isLoading = false;
private static bool _isLoaded = false;
// 备用内置词典(如果 JSON 加载失败)
private static readonly Dictionary<string, string[]> FallbackDict = new Dictionary<string, string[]>
{
// 姓氏(最常用)
{"zhang", new string[] { "张", "章", "长", "丈", "涨" }},
{"wang", new string[] { "王", "望", "忘", "网", "往" }},
{"li", new string[] { "李", "理", "礼", "里", "力", "立" }},
{"zhao", new string[] { "赵", "照", "招", "朝", "兆" }},
{"chen", new string[] { "陈", "沉", "晨", "尘", "辰" }},
{"liu", new string[] { "刘", "流", "留", "柳", "六" }},
{"huang", new string[] { "黄", "皇", "煌", "晃", "荒" }},
{"zhou", new string[] { "周", "州", "洲", "舟", "粥" }},
{"wu", new string[] { "吴", "武", "五", "无", "舞" }},
{"xu", new string[] { "徐", "许", "须", "续", "序" }},
{"sun", new string[] { "孙", "损", "笋", "榫" }},
{"ma", new string[] { "马", "妈", "麻", "码", "吗" }},
{"zhu", new string[] { "朱", "猪", "竹", "主", "住" }},
{"hu", new string[] { "胡", "湖", "虎", "户", "护" }},
{"guo", new string[] { "郭", "国", "果", "过", "锅" }},
{"lin", new string[] { "林", "临", "琳", "霖", "麟" }},
{"he", new string[] { "何", "和", "河", "合", "荷" }},
{"gao", new string[] { "高", "搞", "稿", "告", "膏" }},
{"liang", new string[] { "梁", "良", "凉", "量", "粮" }},
{"zheng", new string[] { "郑", "正", "政", "证", "整" }}
};
// // 常用名字
// {"wei", new string[] { "伟", "伪", "卫", "未", "位", "委" }},
// {"fang", new string[] { "芳", "方", "房", "防", "仿" }},
// {"min", new string[] { "敏", "民", "闵", "珉", "明" }},
// {"xiu", new string[] { "秀", "修", "休", "朽", "锈" }},
// {"ying", new string[] { "英", "影", "应", "迎", "营" }},
// {"jie", new string[] { "杰", "洁", "结", "接", "街" }},
// {"juan", new string[] { "娟", "捐", "卷", "绢", "倦" }},
// {"hua", new string[] { "华", "花", "化", "画", "话" }},
// {"jing", new string[] { "静", "京", "晶", "精", "景" }},
// {"yan", new string[] { "燕", "艳", "严", "言", "颜" }},
// {"hong", new string[] { "红", "洪", "宏", "虹", "鸿" }},
// {"xia", new string[] { "霞", "夏", "侠", "峡", "下" }},
// {"mei", new string[] { "梅", "美", "妹", "媚", "煤" }},
// {"ping", new string[] { "萍", "平", "评", "凭", "屏" }},
// {"yun", new string[] { "云", "运", "韵", "允", "孕" }},
// {"lan", new string[] { "兰", "蓝", "岚", "栏", "览" }},
// {"feng", new string[] { "凤", "风", "峰", "锋", "封" }},
// {"xin", new string[] { "鑫", "新", "心", "信", "欣" }},
// {"lei", new string[] { "磊", "雷", "蕾", "累", "泪" }},
// {"ning", new string[] { "宁", "凝", "柠", "拧", "泞" }},
// // 常用单字
// {"yi", new string[] { "一", "以", "已", "意", "义", "易" }},
// {"er", new string[] { "二", "儿", "尔", "耳", "而" }},
// {"san", new string[] { "三", "散", "伞", "叁" }},
// {"si", new string[] { "四", "死", "思", "私", "司" }},
// {"liu", new string[] { "六", "刘", "流", "留", "柳" }},
// {"qi", new string[] { "七", "其", "期", "齐", "起", "气" }},
// {"ba", new string[] { "八", "巴", "吧", "把", "爸" }},
// {"jiu", new string[] { "九", "久", "酒", "就", "旧" }},
// {"shi", new string[] { "十", "是", "时", "实", "识", "石" }},
// // 常用词组
// {"da", new string[] { "大", "达", "打", "答", "搭" }},
// {"xiao", new string[] { "小", "晓", "笑", "孝", "效" }},
// {"shang", new string[] { "上", "商", "伤", "尚", "赏" }},
// {"xia", new string[] { "下", "夏", "霞", "侠", "峡" }},
// {"zuo", new string[] { "左", "做", "作", "坐", "昨" }},
// {"you", new string[] { "右", "有", "友", "优", "由" }},
// {"dong", new string[] { "东", "动", "冬", "懂", "栋" }},
// {"xi", new string[] { "西", "息", "习", "喜", "系" }},
// {"nan", new string[] { "南", "男", "难", "楠", "囝" }},
// {"bei", new string[] { "北", "被", "背", "备", "杯" }},
// {"zhong", new string[] { "中", "重", "终", "钟", "种" }},
// // 数字相关
// {"ling", new string[] { "零", "灵", "铃", "玲", "凌" }},
// {"yi", new string[] { "一", "衣", "医", "依", "宜" }},
// {"liang", new string[] { "两", "亮", "辆", "量", "梁" }},
// {"bai", new string[] { "百", "白", "拜", "摆", "败" }},
// {"qian", new string[] { "千", "钱", "前", "签", "牵" }},
// {"wan", new string[] { "万", "玩", "完", "晚", "湾" }},
// // 医疗相关
// {"bing", new string[] { "病", "并", "冰", "兵", "丙" }},
// {"huan", new string[] { "患", "换", "唤", "焕", "缓" }},
// {"zhe", new string[] { "者", "这", "着", "折", "哲" }},
// {"yuan", new string[] { "院", "员", "圆", "元", "原" }},
// {"ke", new string[] { "科", "可", "课", "客", "刻" }},
// {"sheng", new string[] { "生", "声", "升", "省", "圣" }},
// {"di", new string[] { "低", "地", "第", "底", "敌" }},
// // 更多常用字
// {"cai", new string[] { "才", "财", "材", "菜", "采" }},
// {"cong", new string[] { "从", "聪", "丛", "葱", "匆" }},
// {"deng", new string[] { "等", "登", "邓", "灯", "凳" }},
// {"fan", new string[] { "范", "反", "饭", "凡", "泛" }},
// {"ge", new string[] { "个", "格", "各", "哥", "歌" }},
// {"han", new string[] { "汉", "韩", "寒", "含", "函" }},
// {"hui", new string[] { "会", "回", "惠", "慧", "辉" }},
// {"jiang", new string[] { "江", "将", "姜", "讲", "蒋" }},
// {"jin", new string[] { "金", "今", "进", "近", "津" }},
// {"kai", new string[] { "开", "凯", "楷", "铠", "慨" }},
// {"kang", new string[] { "康", "抗", "扛", "慷", "糠" }},
// {"kong", new string[] { "孔", "空", "控", "恐", "倥" }},
// {"lai", new string[] { "来", "莱", "赖", "睐", "籁" }},
// {"lao", new string[] { "老", "劳", "涝", "牢", "姥" }},
// {"luo", new string[] { "罗", "洛", "落", "络", "骆" }},
// {"mao", new string[] { "毛", "茂", "冒", "帽", "茅" }},
// {"meng", new string[] { "梦", "孟", "蒙", "猛", "盟" }},
// {"mo", new string[] { "莫", "末", "默", "墨", "摸" }},
// {"pei", new string[] { "培", "佩", "配", "裴", "沛" }},
// {"peng", new string[] { "鹏", "彭", "朋", "蓬", "碰" }},
// {"qiang", new string[] { "强", "墙", "枪", "抢", "腔" }},
// {"qin", new string[] { "秦", "勤", "琴", "侵", "钦" }},
// {"qing", new string[] { "青", "清", "情", "请", "晴" }},
// {"qiu", new string[] { "秋", "求", "球", "丘", "邱" }},
// {"quan", new string[] { "全", "权", "泉", "圈", "劝" }},
// {"ren", new string[] { "人", "任", "仁", "认", "忍" }},
// {"rong", new string[] { "荣", "容", "融", "溶", "绒" }},
// {"rou", new string[] { "柔", "肉", "揉", "糅", "蹂" }},
// {"rui", new string[] { "瑞", "锐", "芊", "睿", "蕊" }},
// {"sen", new string[] { "森", "参", "深", "审", "婶" }},
// {"sha", new string[] { "沙", "砂", "莎", "杀", "纱" }},
// {"shen", new string[] { "申", "沈", "深", "神", "审" }},
// {"shou", new string[] { "寿", "手", "守", "首", "受" }},
// {"shu", new string[] { "树", "书", "数", "术", "蜀" }},
// {"shui", new string[] { "水", "睡", "税", "说", "谁" }},
// {"song", new string[] { "宋", "送", "松", "颂", "诵" }},
// {"su", new string[] { "苏", "素", "速", "肃", "俗" }},
// {"tai", new string[] { "台", "太", "泰", "态", "胎" }},
// {"tan", new string[] { "谭", "谈", "坛", "探", "叹" }},
// {"tang", new string[] { "唐", "堂", "糖", "汤", "塘" }},
// {"tao", new string[] { "陶", "桃", "涛", "淘", "逃" }},
// {"tian", new string[] { "田", "天", "甜", "填", "添" }},
// {"tong", new string[] { "同", "通", "童", "桐", "统" }},
// {"tu", new string[] { "图", "土", "途", "徒", "突" }},
// {"wen", new string[] { "文", "温", "闻", "稳", "问" }},
// {"xiang", new string[] { "向", "香", "乡", "相", "祥" }},
// {"xie", new string[] { "谢", "写", "解", "些", "协" }},
// {"xing", new string[] { "兴", "星", "行", "性", "姓" }},
// {"xiong", new string[] { "熊", "雄", "兄", "胸", "凶" }},
// {"yang", new string[] { "杨", "阳", "洋", "扬", "羊" }},
// {"yao", new string[] { "姚", "要", "药", "摇", "遥" }},
// {"ye", new string[] { "叶", "业", "夜", "页", "野" }},
// {"yu", new string[] { "于", "余", "鱼", "玉", "雨", "宇" }},
// {"yue", new string[] { "月", "越", "岳", "悦", "乐" }},
// {"ze", new string[] { "泽", "则", "择", "责", "啧" }},
// {"zeng", new string[] { "曾", "增", "赠", "憎", "锃" }},
// {"zhan", new string[] { "占", "战", "站", "展", "湛" }},
// {"zhi", new string[] { "志", "智", "之", "知", "制", "治" }},
// {"zhong", new string[] { "中", "重", "终", "钟", "种" }},
// };
/// <summary>
/// 初始化拼音词库(从 StreamingAssets 加载)
/// </summary>
public static IEnumerator Initialize()
{
if (_isLoaded || _isLoading)
yield break;
_isLoading = true;
string filePath = Path.Combine(Application.streamingAssetsPath, "pinyin_dict.json");
UnityWebRequest www = UnityWebRequest.Get(filePath);
yield return www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
try
{
string json = www.downloadHandler.text;
PinyinDict = ParsePinyinJson(json);
_isLoaded = true;
Debug.Log($"拼音词库加载成功:共 {PinyinDict.Count} 个拼音");
}
catch (Exception e)
{
Debug.LogError($"解析拼音词库失败: {e.Message}");
PinyinDict = FallbackDict;
_isLoaded = true;
}
}
else
{
Debug.LogWarning($"加载拼音词库失败: {www.error},使用内置词典");
PinyinDict = FallbackDict;
_isLoaded = true;
}
_isLoading = false;
}
/// <summary>
/// 解析 JSON 格式的拼音词典
/// </summary>
// 安装 NuGet 包或 Unity 包管理器中的 Json.NET
private static Dictionary<string, string[]> ParsePinyinJson(string json)
{
return JsonConvert.DeserializeObject<Dictionary<string, string[]>>(json);
}
// private static Dictionary<string, string[]> ParsePinyinJson(string json)
// {
// var dict = new Dictionary<string, string[]>();
// // 由于 Unity JsonUtility 不支持 Dictionary我们手动解析
// int startIndex = json.IndexOf('{') + 1;
// int endIndex = json.LastIndexOf('}');
// string content = json.Substring(startIndex, endIndex - startIndex);
// // 简化解析:查找 "pinyin": [array] 模式
// string[] entries = content.Split(new[] { "\",\n \"" }, StringSplitOptions.RemoveEmptyEntries);
// foreach (var entry in entries)
// {
// int colonIndex = entry.IndexOf("\":");
// if (colonIndex < 0) continue;
// string key = entry.Substring(0, colonIndex).Trim().Trim('"');
// int arrayStart = entry.IndexOf('[', colonIndex);
// int arrayEnd = entry.IndexOf(']', arrayStart);
// if (arrayStart < 0 || arrayEnd < 0) continue;
// string arrayContent = entry.Substring(arrayStart + 1, arrayEnd - arrayStart - 1);
// string[] chars = arrayContent.Split(new[] { "\",\n \"", "\", \"" }, StringSplitOptions.RemoveEmptyEntries);
// List<string> validChars = new List<string>();
// foreach (var c in chars)
// {
// string cleaned = c.Trim().Trim('"').Trim();
// if (!string.IsNullOrEmpty(cleaned))
// validChars.Add(cleaned);
// }
// if (validChars.Count > 0)
// {
// dict[key] = validChars.ToArray();
// }
// }
// return dict;
// }
/// <summary>
/// 根据拼音获取候选汉字
/// </summary>
public static string[] GetCandidates(string pinyin)
{
if (string.IsNullOrEmpty(pinyin))
return new string[0];
// 如果词库未加载,使用备用词典
var currentDict = PinyinDict ?? FallbackDict;
string key = pinyin.ToLower().Trim();
if (currentDict.ContainsKey(key))
{
var candidates = currentDict[key];
// 过滤掉生僻字Unicode > 0x9FFF 的字符)和不常用字
List<string> validCandidates = new List<string>();
foreach (var c in candidates)
{
if (string.IsNullOrEmpty(c) || c.Length == 0)
continue;
// 获取第一个字符的 Unicode 码点
int unicode = char.ConvertToUtf32(c, 0);
// 只保留常用汉字范围基本汉字0x4E00-0x9FFF
// 这个范围包含了 20902 个最常用的汉字
if (unicode >= 0x4E00 && unicode <= 0x9FFF)
{
validCandidates.Add(c);
}
// 如果已经有足够多的候选字,就停止
if (validCandidates.Count >= 50)
break;
}
return validCandidates.ToArray();
}
return new string[0];
}
/// <summary>
/// 检查词库是否已加载
/// </summary>
public static bool IsLoaded()
{
return _isLoaded;
}
/// <summary>
/// 检查是否是有效的拼音
/// </summary>
public static bool IsValidPinyin(string pinyin)
{
if (string.IsNullOrEmpty(pinyin))
return false;
return PinyinDict.ContainsKey(pinyin.ToLower().Trim());
}
/// <summary>
/// 获取所有支持的拼音列表
/// </summary>
public static List<string> GetAllPinyins()
{
return new List<string>(PinyinDict.Keys);
}
}