337 lines
16 KiB
C#
337 lines
16 KiB
C#
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);
|
||
}
|
||
}
|