using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; namespace BFEditor { public class EmojiEditor : EditorWindow { [MenuItem("BF编辑器/Emoji表情配置")] public static void EmojiConfiguration() { EmojiEditor window = ScriptableObject.CreateInstance(); window.ShowUtility(); } void OnInspectorUpdate() { Repaint(); } private int emojiSize = 0; private int columnCount = 0; //读取PNG路径 private const string READ_EMOJI_PATH_PREFS = "read_emoji_path"; private string readEmojiPath = ""; //生成texture路径 private const string GET_EMOJI_PATH_PREFS = "tar_emoji_path"; private string tarEmojiPath = ""; //配置表路径 private const string CONFIG_PATH_PREFS = "emoji_config_path"; private string tarCfgPath = ""; private string newTextureName = "emoji_total"; private string cfgName = "emoji_info"; private Dictionary>> emojiUVs = new Dictionary>>(); public void OnGUI() { emojiSize = EditorGUILayout.IntField("单个表情像素", emojiSize); EditorGUILayout.Space(); columnCount = EditorGUILayout.IntField("图片表情列数", columnCount); EditorGUILayout.Space(); //emoji路径 if (GUILayout.Button("选择读取Emoji目标路径")) { var readEmojiPath = EditorUtility.OpenFolderPanel("生成png目标文件夹", "", ""); if (!string.IsNullOrEmpty(readEmojiPath)) { PlayerPrefs.SetString(READ_EMOJI_PATH_PREFS, readEmojiPath); } } readEmojiPath = PlayerPrefs.GetString(READ_EMOJI_PATH_PREFS, ""); EditorGUILayout.LabelField("读取Emoji文件路径", readEmojiPath); EditorGUILayout.Space(); //生成目标路径 if (GUILayout.Button("选择生成目标路径")) { var tarGetPath = EditorUtility.OpenFolderPanel("生成png目标文件夹", "", ""); if (!string.IsNullOrEmpty(tarGetPath)) { PlayerPrefs.SetString(GET_EMOJI_PATH_PREFS, tarGetPath); } } tarEmojiPath = PlayerPrefs.GetString(GET_EMOJI_PATH_PREFS, ""); EditorGUILayout.LabelField("生成PNG文件路径", tarEmojiPath); //生成PNG名 newTextureName = EditorGUILayout.TextField("生成PNG名", newTextureName); EditorGUILayout.Space(); //配置表路径 if (GUILayout.Button("选择配置表目标路径")) { var tarCfgPath = EditorUtility.OpenFolderPanel("生成配置表目标文件夹", "", ""); if (!string.IsNullOrEmpty(tarCfgPath)) { PlayerPrefs.SetString(CONFIG_PATH_PREFS, tarCfgPath); } } tarCfgPath = PlayerPrefs.GetString(CONFIG_PATH_PREFS, ""); EditorGUILayout.LabelField("生成配置表文件路径", tarCfgPath); cfgName = EditorGUILayout.TextField("生成配置表名", cfgName); EditorGUILayout.Space(); //合成PNG if (GUILayout.Button("合成PNG并生成配置")) { if (string.IsNullOrEmpty(tarEmojiPath)) { EditorUtility.DisplayDialog("提示", "没有指定PNG生成文件夹路径", "确定"); return; } if (!Directory.Exists(tarEmojiPath)) { EditorUtility.DisplayDialog("提示", "生成PNG文件夹路径不存在", "确定"); return; } if (string.IsNullOrEmpty(readEmojiPath)) { EditorUtility.DisplayDialog("提示", "没有指定读取emoji文件夹路径", "确定"); return; } if (!Directory.Exists(readEmojiPath)) { EditorUtility.DisplayDialog("提示", "读取emoji文件夹路径不存在", "确定"); return; } if (string.IsNullOrEmpty(tarCfgPath)) { EditorUtility.DisplayDialog("提示", "没有指定配置表文件夹路径", "确定"); return; } if (!Directory.Exists(tarCfgPath)) { EditorUtility.DisplayDialog("提示", "配置表文件夹路径不存在", "确定"); return; } EncodePng(); SaveUVsConfig(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.DisplayDialog("提示", "生成PNG和配置表完成", "确定"); } } private void EncodePng() { if (emojiSize == 0 || columnCount == 0) { EditorUtility.DisplayDialog("提示", "表情参数不正确", "确定"); return; } emojiUVs.Clear(); //先计算生成texture大小 var width = emojiSize * columnCount; var exp = 1; while (exp < width) { exp <<= 1; } width = exp; var height = 0; //读取totalCount var pngs = Directory.GetFiles(readEmojiPath, "*.png"); Debug.Log("表情总数 " + pngs.Length); var totalCount = pngs.Length; var otherNum = totalCount % columnCount; if (otherNum == 0) { height = (int)Mathf.Ceil(totalCount / columnCount) * emojiSize; } else { height = ((int)(totalCount / columnCount) + 1)* emojiSize; } exp = 1; while (exp < height) { exp <<= 1; } height = exp; var newTexture = new Texture2D(width, height, TextureFormat.ARGB32, false); var tmpPngPath = ""; var row = 0; var column = 0; var countDown = 0; foreach (var pngPath in pngs) { tmpPngPath = pngPath.Substring(pngPath.IndexOf("Assets")); tmpPngPath = tmpPngPath.Replace('\\', '/'); var texture = (Texture2D)AssetDatabase.LoadAssetAtPath(tmpPngPath, typeof(Texture2D)); if (texture.width != emojiSize || texture.height != emojiSize) { Debug.LogErrorFormat("{0} 表情大小不符合规范 width : {1} height : {2}", texture.name, texture.width, texture.height); return; } Color32[] colors = texture.GetPixels32(); row = countDown % columnCount; column = countDown / columnCount; //画上去 var xPos = row * emojiSize; var yPos = column * emojiSize; newTexture.SetPixels32(xPos, yPos, emojiSize, emojiSize, colors); //config if (!Regex.IsMatch(texture.name,@"emoji\d{1,}_\d{1,}")) { Debug.LogErrorFormat("{0} 表情名称不符合规范", texture.name); return; } var index1 = texture.name.Substring(5, 1); var index2 = int.Parse(texture.name.Split('_')[1]); var emojiTypeIndex = int.Parse(index1); Dictionary> emojiInfos; if (!emojiUVs.TryGetValue(emojiTypeIndex, out emojiInfos)) { emojiInfos = new Dictionary>(); emojiUVs.Add(emojiTypeIndex, emojiInfos); } var uvs = new List(8); Debug.LogWarning(xPos); Debug.LogWarning(yPos); Debug.LogWarning(width); Debug.LogWarning(height); uvs.Add((float)xPos / width); //uv0 uvs.Add((float)(yPos + emojiSize) / height); uvs.Add((float)(xPos + emojiSize) / width); //uv1 uvs.Add((float)(yPos + emojiSize) / height); uvs.Add((float)(xPos + emojiSize) / width); //uv2 uvs.Add((float)yPos / height); uvs.Add((float)xPos / width); //uv3 uvs.Add((float)yPos / height); emojiInfos.Add(index2, uvs); countDown++; } newTexture.Apply(); string path = tarEmojiPath + "/" + newTextureName + ".png"; File.WriteAllBytes(path, newTexture.EncodeToPNG()); } private void SaveUVsConfig() { StringBuilder sb = new StringBuilder(); string space = "\t"; string doubleSpace = "\t\t"; string tripleSpace = "\t\t\t"; string fourthSpace = "\t\t\t\t"; sb.Append("local emojiInfo = {\n"); foreach (var pairs in emojiUVs) { sb.Append(space + "[" + (pairs.Key) + "] = {\n"); var countDown = 1; foreach (var _pairs in pairs.Value) { sb.Append(doubleSpace + "[" + countDown + "] = {\n"); sb.Append(tripleSpace + "[1] = " + _pairs.Value[0] + ",\n"); sb.Append(tripleSpace + "[2] = " + _pairs.Value[1] + ",\n"); sb.Append(tripleSpace + "[3] = " + _pairs.Value[2] + ",\n"); sb.Append(tripleSpace + "[4] = " + _pairs.Value[3] + ",\n"); sb.Append(tripleSpace + "[5] = " + _pairs.Value[4] + ",\n"); sb.Append(tripleSpace + "[6] = " + _pairs.Value[5] + ",\n"); sb.Append(tripleSpace + "[7] = " + _pairs.Value[6] + ",\n"); sb.Append(tripleSpace + "[8] = " + _pairs.Value[7] + ",\n"); sb.Append(doubleSpace + "},\n"); countDown++; } sb.Append(space + "},\n"); } sb.Append("}\n"); sb.Append("return emojiInfo"); using (StreamWriter fs = new StreamWriter(tarCfgPath + "/" + cfgName + ".lua")) { Debug.Log(sb.ToString()); fs.Write(sb.ToString()); } // using (FileStream fs = File.Open(tarCfgPath + "/" + cfgName + ".lua", FileMode.Create)) // { // BinaryWriter bw = new BinaryWriter(fs); // bw.Write(sb.ToString()); // } Close(); } } }