|
| 1 | +using System; |
| 2 | +using System.Collections; |
| 3 | +using System.Collections.Generic; |
| 4 | +using System.IO; |
| 5 | +using UnityEditor; |
| 6 | +using UnityEngine; |
| 7 | +using UnityEngine.UI; |
| 8 | +using Object = UnityEngine.Object; |
| 9 | + |
| 10 | +public class GTextBuilder |
| 11 | +{ |
| 12 | + |
| 13 | + private static readonly Vector2[] AtlasSize = new Vector2[] |
| 14 | + { |
| 15 | + new Vector2(32, 32), |
| 16 | + new Vector2(64, 64), |
| 17 | + new Vector2(128, 128), |
| 18 | + new Vector2(256, 256), |
| 19 | + new Vector2(512, 512), |
| 20 | + new Vector2(1024, 1024), |
| 21 | + new Vector2(2048, 2048) |
| 22 | + }; |
| 23 | + |
| 24 | + class AssetInfor |
| 25 | + { |
| 26 | + public int index; |
| 27 | + public Object obj; |
| 28 | + } |
| 29 | + |
| 30 | + class SpriteInfo |
| 31 | + { |
| 32 | + public string key; |
| 33 | + public string x; |
| 34 | + public string y; |
| 35 | + public string size; |
| 36 | + } |
| 37 | + |
| 38 | + static int EmojiSize = 32; |
| 39 | + |
| 40 | + |
| 41 | + [MenuItem("Assets/Build Emoji")] |
| 42 | + public static void BuildEmoji() |
| 43 | + { |
| 44 | + List<char> keylist = new List<char>(); |
| 45 | + for (int i = 48; i <= 57; i++) |
| 46 | + { |
| 47 | + keylist.Add(System.Convert.ToChar(i)); //0-9 |
| 48 | + } |
| 49 | + for (int i = 65; i <= 90; i++) |
| 50 | + { |
| 51 | + keylist.Add(System.Convert.ToChar(i)); //A-Z |
| 52 | + } |
| 53 | + for (int i = 97; i <= 122; i++) |
| 54 | + { |
| 55 | + keylist.Add(System.Convert.ToChar(i)); //a-z |
| 56 | + } |
| 57 | + |
| 58 | + |
| 59 | + int totalFrames = 0; |
| 60 | + Dictionary<string, List<AssetInfor>> sourceDic = new Dictionary<string, List<AssetInfor>>(); |
| 61 | + Object[] textures = Selection.GetFiltered(typeof(Texture), SelectionMode.DeepAssets); |
| 62 | + //search all emojis and compute they frames. |
| 63 | + for (int i = 0; i < textures.Length; i++) |
| 64 | + { |
| 65 | + string path = AssetDatabase.GetAssetPath(textures[i]); |
| 66 | + if (!path.EndsWith(".png")) |
| 67 | + continue; |
| 68 | + string filename = Path.GetFileNameWithoutExtension(path); |
| 69 | + string[] t = filename.Split('_'); |
| 70 | + string id = t[0]; |
| 71 | + int index = 1; |
| 72 | + if (t.Length > 1) |
| 73 | + if (!int.TryParse(t[1], out index)) |
| 74 | + { |
| 75 | + Debug.LogError(path + " 's Name Error! You Should Name 'name_index'"); |
| 76 | + continue; |
| 77 | + } |
| 78 | + |
| 79 | + if (!sourceDic.ContainsKey(id)) |
| 80 | + { |
| 81 | + sourceDic.Add(id, new List<AssetInfor>()); |
| 82 | + } |
| 83 | + sourceDic[id].Add(new AssetInfor() { index = index, obj = textures[i] }); |
| 84 | + totalFrames++; |
| 85 | + } |
| 86 | + List<string> keys = new List<string>(sourceDic.Keys); |
| 87 | + for (int i = 0; i < keys.Count; i++) |
| 88 | + { |
| 89 | + sourceDic[keys[i]].Sort( |
| 90 | + new Comparison<AssetInfor>((AssetInfor a, AssetInfor b) => a.index <= b.index ? 1 : 0)); |
| 91 | + } |
| 92 | + |
| 93 | + Dictionary<string, SpriteInfo> emojiDic = new Dictionary<string, SpriteInfo>(); |
| 94 | + Vector2 texSize = ComputeAtlasSize(totalFrames); |
| 95 | + Texture2D newTex = new Texture2D((int)texSize.x, (int)texSize.y, TextureFormat.ARGB32, false); |
| 96 | + for (int i = 0; i < newTex.width; i++) |
| 97 | + { |
| 98 | + //Set original texture alpha 0 |
| 99 | + for (int j = 0; j < newTex.height; j++) |
| 100 | + { |
| 101 | + newTex.SetPixel(i, j, new Color(1, 1, 1, 0)); |
| 102 | + } |
| 103 | + } |
| 104 | + int lineCount = (int)texSize.x / EmojiSize; |
| 105 | + Texture2D dataTex = new Texture2D(lineCount, (int)texSize.y / EmojiSize, TextureFormat.ARGB32, false); |
| 106 | + |
| 107 | + int x = 0, y = 0, keyindex = 0; |
| 108 | + foreach (string key in sourceDic.Keys) |
| 109 | + { |
| 110 | + var list = sourceDic[key]; |
| 111 | + for (int i = 0; i < list.Count; i++) |
| 112 | + { |
| 113 | + Texture2D texture = list[i].obj as Texture2D; |
| 114 | + Color[] colors = texture.GetPixels(0, 0, EmojiSize, EmojiSize); |
| 115 | + newTex.SetPixels(x, y, EmojiSize, EmojiSize, colors); |
| 116 | + |
| 117 | + string t = System.Convert.ToString(sourceDic[key].Count - 1, 2); |
| 118 | + float r = 0, g = 0, b = 0; |
| 119 | + if (t.Length >= 3) |
| 120 | + { |
| 121 | + r = t[2] == '1' ? 0.5f : 0; |
| 122 | + g = t[1] == '1' ? 0.5f : 0; |
| 123 | + b = t[0] == '1' ? 0.5f : 0; |
| 124 | + } |
| 125 | + else if (t.Length >= 2) |
| 126 | + { |
| 127 | + r = t[1] == '1' ? 0.5f : 0; |
| 128 | + g = t[0] == '1' ? 0.5f : 0; |
| 129 | + } |
| 130 | + else |
| 131 | + { |
| 132 | + r = t[0] == '1' ? 0.5f : 0; |
| 133 | + } |
| 134 | + |
| 135 | + dataTex.SetPixel(x / EmojiSize, y / EmojiSize, new Color(r, g, b, 1)); |
| 136 | + |
| 137 | + if (!emojiDic.ContainsKey(key)) |
| 138 | + { |
| 139 | + SpriteInfo info = new SpriteInfo(); |
| 140 | + if (keyindex < keylist.Count) |
| 141 | + { |
| 142 | + info.key = "[" + char.ToString(keylist[keyindex]) + "]"; |
| 143 | + } |
| 144 | + else |
| 145 | + { |
| 146 | + info.key = "[" + char.ToString(keylist[keyindex / keylist.Count]) + |
| 147 | + char.ToString(keylist[keyindex % keylist.Count]) + "]"; |
| 148 | + } |
| 149 | + info.x = (x * 1.0f / texSize.x).ToString(); |
| 150 | + info.y = (y * 1.0f / texSize.y).ToString(); |
| 151 | + info.size = (EmojiSize * 1.0f / texSize.x).ToString(); |
| 152 | + |
| 153 | + emojiDic.Add(key, info); |
| 154 | + keyindex++; |
| 155 | + } |
| 156 | + |
| 157 | + x += EmojiSize; |
| 158 | + if (x >= texSize.x) |
| 159 | + { |
| 160 | + x = 0; |
| 161 | + y += EmojiSize; |
| 162 | + } |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + string saveFolder = EditorUtility.SaveFolderPanel("Select Folder To Save Data", "Assets/", ""); |
| 167 | + |
| 168 | + byte[] bytes1 = newTex.EncodeToPNG(); |
| 169 | + string outputfile1 = saveFolder + "/emoji_tex.png"; |
| 170 | + File.WriteAllBytes(outputfile1, bytes1); |
| 171 | + byte[] bytes2 = dataTex.EncodeToPNG(); |
| 172 | + string outputfile2 = saveFolder + "/emoji_data.png"; |
| 173 | + File.WriteAllBytes(outputfile2, bytes2); |
| 174 | + |
| 175 | + using (StreamWriter sw = new StreamWriter(saveFolder + "/Emoji.txt", false)) |
| 176 | + { |
| 177 | + sw.WriteLine("Name\tKey\tFrames\tX\tY\tSize"); |
| 178 | + foreach (string key in emojiDic.Keys) |
| 179 | + { |
| 180 | + sw.WriteLine("{" + key + "}\t" + emojiDic[key].key + "\t" + sourceDic[key].Count + "\t" + emojiDic[key].x + "\t" + emojiDic[key].y + "\t" + emojiDic[key].size); |
| 181 | + } |
| 182 | + sw.Close(); |
| 183 | + } |
| 184 | + AssetDatabase.Refresh(); |
| 185 | + FormatTexture("Assets/" + saveFolder.Split(new[] { "Assets/" }, StringSplitOptions.None)[1]); |
| 186 | + |
| 187 | + Material material = new Material(Shader.Find("UI/EmojiFont")); |
| 188 | + Texture2D emojiTex = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/" + outputfile1.Split(new[] { "Assets/" }, StringSplitOptions.None)[1]); |
| 189 | + material.SetTexture("_EmojiTex", emojiTex); |
| 190 | + |
| 191 | + Texture2D emojiData = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/" + outputfile2.Split(new[] { "Assets/" }, StringSplitOptions.None)[1]); |
| 192 | + material.SetTexture("_EmojiDataTex", emojiData); |
| 193 | + material.SetFloat("_EmojiSize", lineCount); |
| 194 | + AssetDatabase.CreateAsset(material, "Assets/" + saveFolder.Split(new[] { "Assets/" }, StringSplitOptions.None)[1] + "/Emoji.mat"); |
| 195 | + } |
| 196 | + |
| 197 | + private static Vector2 ComputeAtlasSize(int count) |
| 198 | + { |
| 199 | + long total = count * EmojiSize * EmojiSize; |
| 200 | + for (int i = 0; i < AtlasSize.Length; i++) |
| 201 | + { |
| 202 | + if (total <= AtlasSize[i].x * AtlasSize[i].y) |
| 203 | + { |
| 204 | + return AtlasSize[i]; |
| 205 | + } |
| 206 | + } |
| 207 | + return Vector2.zero; |
| 208 | + } |
| 209 | + |
| 210 | + private static void FormatTexture(string OutputPath) |
| 211 | + { |
| 212 | + TextureImporter emojiTex = AssetImporter.GetAtPath(OutputPath + "/emoji_tex.png") as TextureImporter; |
| 213 | + emojiTex.filterMode = FilterMode.Point; |
| 214 | + emojiTex.mipmapEnabled = false; |
| 215 | + emojiTex.sRGBTexture = true; |
| 216 | + emojiTex.alphaSource = TextureImporterAlphaSource.FromInput; |
| 217 | + emojiTex.SaveAndReimport(); |
| 218 | + |
| 219 | + TextureImporter emojiData = AssetImporter.GetAtPath(OutputPath + "/emoji_data.png") as TextureImporter; |
| 220 | + emojiData.filterMode = FilterMode.Point; |
| 221 | + emojiData.mipmapEnabled = false; |
| 222 | + emojiData.sRGBTexture = false; |
| 223 | + emojiData.alphaSource = TextureImporterAlphaSource.None; |
| 224 | + emojiData.SaveAndReimport(); |
| 225 | + } |
| 226 | + |
| 227 | + [MenuItem("GameObject/UI/Text->GText")] |
| 228 | + static void Text2GText() |
| 229 | + { |
| 230 | + UnityEngine.Object select = Selection.activeObject; |
| 231 | + if (select == null) |
| 232 | + return; |
| 233 | + GameObject target = select as GameObject; |
| 234 | + Text text = target.GetComponent<Text>(); |
| 235 | + if (text == null) |
| 236 | + return; |
| 237 | + string content = text.text; |
| 238 | + Font font = text.font; |
| 239 | + FontStyle fs = text.fontStyle; |
| 240 | + int fontsize = text.fontSize; |
| 241 | + float lineSpacing = text.lineSpacing; |
| 242 | + Color color = text.color; |
| 243 | + |
| 244 | + GameObject.DestroyImmediate(text); |
| 245 | + GText gText = target.AddComponent<GText>(); |
| 246 | + gText.text = content; |
| 247 | + gText.font = font; |
| 248 | + gText.fontSize = fontsize; |
| 249 | + gText.fontStyle = fs; |
| 250 | + gText.lineSpacing = lineSpacing; |
| 251 | + gText.color = color; |
| 252 | + gText.raycastTarget = true; |
| 253 | + gText.supportRichText = true; |
| 254 | + |
| 255 | + |
| 256 | + Material material = AssetDatabase.LoadAssetAtPath<Material>("Assets/GText/Resources/Emoji.mat"); |
| 257 | + if(material == null) |
| 258 | + Debug.LogError("Can not find material Use UI-EmojiFount "); |
| 259 | + else |
| 260 | + gText.material = material; |
| 261 | + |
| 262 | + } |
| 263 | +} |
0 commit comments