2023-04-03 11:04:31 +08:00

303 lines
10 KiB
C#

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<EmojiEditor>();
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<int,Dictionary<int, List<float>>> emojiUVs = new Dictionary<int, Dictionary<int, List<float>>>();
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<int, List<float>> emojiInfos;
if (!emojiUVs.TryGetValue(emojiTypeIndex, out emojiInfos))
{
emojiInfos = new Dictionary<int, List<float>>();
emojiUVs.Add(emojiTypeIndex, emojiInfos);
}
var uvs = new List<float>(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();
}
}
}