/// <summary> /// Create and add new default material to sprite asset. /// </summary> /// <param name="spriteAsset"></param> private static void AddDefaultMaterial(TMP_SpriteAsset spriteAsset) { Shader shader = Shader.Find("TMPro/Sprite"); Material material = new Material(shader); material.SetTexture(ShaderUtilities.ID_MainTex, spriteAsset.spriteSheet); spriteAsset.material = material; material.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(material, spriteAsset); }
internal static void Init() { On.RoR2.Glyphs.GetGlyphString_MPEventSystem_string_AxisRange_InputSource += GetCustomGlyphString; On.RoR2.InputBindingDisplayController.Awake += ApplyInputDisplaySpriteAsset; On.RoR2.UI.ContextManager.Awake += ApplyContextSpriteAsset; On.RoR2.UI.MPEventSystem.OnLastActiveControllerChanged += ChangedToCustom; glyphsSpriteAsset = VRMod.VRAssetBundle.LoadAsset <TMP_SpriteAsset>("sprVRGlyphs"); if (ModConfig.InitialOculusModeValue) { currentGlyphs = standardGlyphs; return; } RoR2Application.onUpdate += FindControllerType; }
public void ShowTMProWarning(Shader shader, Shader mobileShader, Shader spriteShader, System.Action <Material> onCreatedMaterial) { #if UNITY_EDITOR && TMP_PRESENT if (!textMeshPro || !textMeshPro.fontSharedMaterial) { return; } // Is the material preset for dissolve? Material m = textMeshPro.fontSharedMaterial; if (m.shader != shader && m.shader != mobileShader) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox(string.Format("{0} requires '{1}' or '{2}' as a shader for material preset.", GetType().Name, shader.name, mobileShader.name), MessageType.Warning); if (GUILayout.Button("Fix")) { var correctShader = m.shader.name.Contains("Mobile") ? mobileShader : shader; textMeshPro.fontSharedMaterial = ModifyTMProMaterialPreset(m, correctShader, onCreatedMaterial); } EditorGUILayout.EndHorizontal(); return; } // Is the sprite asset for dissolve? TMP_SpriteAsset spriteAsset = textMeshPro.spriteAsset ?? TMP_Settings.GetSpriteAsset(); m = spriteAsset.material; if (m && m.shader != spriteShader && textMeshPro.richText && textMeshPro.text.Contains("<sprite=")) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox(string.Format("{0} requires '{1}' as a shader for sprite asset.", GetType().Name, spriteShader.name), MessageType.Warning); if (GUILayout.Button("Fix")) { GetComponentsInChildren <TMP_SubMesh> ().Select(x => x.gameObject).ToList().ForEach(DestroyImmediate); GetComponentsInChildren <TMP_SubMeshUI> ().Select(x => x.gameObject).ToList().ForEach(DestroyImmediate); textMeshPro.spriteAsset = ModifyTMProSpriteAsset(m, spriteShader, onCreatedMaterial); } EditorGUILayout.EndHorizontal(); return; } }
public void OnPreprocessBuild(BuildReport report) { TMP_SpriteAsset spriteAsset = GetSpriteAsset(); if (spriteAsset != null) { Texture spriteSheet = GetSpriteSheet(target: report.summary.platform); if (spriteSheet != null) { spriteAsset.spriteSheet = spriteSheet; } else { Debug.LogErrorFormat("SpriteSheet texture couldn't be found for {0}", report.summary.platform); } } else { Debug.LogErrorFormat("SpriteAsset couldn't be loaded at path: {0}", _emojiSpriteAssetPath); } }
public static void HookTMP(TMP_Text tmp_Text) { if (tmp_Text == null) { return; } if (rootEmojiAsset == null) { canCopyTextures = SystemInfo.copyTextureSupport != UnityEngine.Rendering.CopyTextureSupport.None; rootEmojiAsset = CreateTMP_SpriteAsset(); currentEmojiAsset = rootEmojiAsset; currentEmojiIndex = 0; } if (emojiTexture == null) { emojiTexture = new EmojiTexture(EMOJI_SIZE); } if (tmp_Text.spriteAsset == null) { tmp_Text.spriteAsset = rootEmojiAsset; } else if (tmp_Text.spriteAsset != rootEmojiAsset) { if (tmp_Text.spriteAsset.fallbackSpriteAssets == null) { tmp_Text.spriteAsset.fallbackSpriteAssets = new List <TMP_SpriteAsset>(); } if (!tmp_Text.spriteAsset.fallbackSpriteAssets.Contains(rootEmojiAsset)) { tmp_Text.spriteAsset.fallbackSpriteAssets.Add(rootEmojiAsset); } } }
public static void CreateTextMeshProObjectPerform() { Object activeObject = Selection.activeObject; if (activeObject == null || activeObject.GetType() != typeof(Texture2D)) { Debug.LogWarning("A texture which contains sprites must first be selected in order to create a TextMesh Pro Sprite Asset."); return; } Texture2D texture2D = activeObject as Texture2D; string assetPath = AssetDatabase.GetAssetPath(texture2D); string fileName = Path.GetFileName(assetPath); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(assetPath); string str = assetPath.Replace(fileName, ""); TMP_SpriteAsset tMP_SpriteAsset = AssetDatabase.LoadAssetAtPath(str + fileNameWithoutExtension + ".asset", typeof(TMP_SpriteAsset)) as TMP_SpriteAsset; if ((tMP_SpriteAsset == null) ? true : false) { tMP_SpriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>(); AssetDatabase.CreateAsset(tMP_SpriteAsset, str + fileNameWithoutExtension + ".asset"); tMP_SpriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(tMP_SpriteAsset.name); tMP_SpriteAsset.spriteSheet = texture2D; tMP_SpriteAsset.spriteInfoList = GetSpriteInfo(texture2D); AddDefaultMaterial(tMP_SpriteAsset); } else { tMP_SpriteAsset.spriteInfoList = UpdateSpriteInfo(tMP_SpriteAsset); if (tMP_SpriteAsset.material == null) { AddDefaultMaterial(tMP_SpriteAsset); } } EditorUtility.SetDirty(tMP_SpriteAsset); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tMP_SpriteAsset)); }
public void OnEnable() { m_SpriteAsset = target as TMP_SpriteAsset; m_spriteAtlas_prop = serializedObject.FindProperty("spriteSheet"); m_material_prop = serializedObject.FindProperty("material"); m_SpriteCharacterTableProperty = serializedObject.FindProperty("m_SpriteCharacterTable"); m_SpriteGlyphTableProperty = serializedObject.FindProperty("m_SpriteGlyphTable"); // Fallback TMP Sprite Asset list m_fallbackSpriteAssetList = new ReorderableList(serializedObject, serializedObject.FindProperty("fallbackSpriteAssets"), true, true, true, true); m_fallbackSpriteAssetList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = m_fallbackSpriteAssetList.serializedProperty.GetArrayElementAtIndex(index); rect.y += 2; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element, GUIContent.none); }; m_fallbackSpriteAssetList.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, new GUIContent("Fallback Sprite Asset List", "Select the Sprite Assets that will be searched and used as fallback when a given sprite is missing from this sprite asset.")); }; }
public static void HookTMP(TMP_Text tmp_Text) { if (tmp_Text == null) { return; } if (rootEmojiAsset == null) { rootEmojiAsset = CreateTMP_SpriteAsset(); currentEmojiAsset = rootEmojiAsset; currentEmojiIndex = 0; } if (emojiTexture == null) { emojiTexture = new EmojiTexture(EMOJI_SIZE); } if (tmp_Text.spriteAsset == null) { tmp_Text.spriteAsset = rootEmojiAsset; } else if (tmp_Text.spriteAsset != rootEmojiAsset) { if (tmp_Text.spriteAsset.fallbackSpriteAssets == null) { tmp_Text.spriteAsset.fallbackSpriteAssets = new List <TMP_SpriteAsset>(); } if (!tmp_Text.spriteAsset.fallbackSpriteAssets.Contains(rootEmojiAsset)) { tmp_Text.spriteAsset.fallbackSpriteAssets.Add(rootEmojiAsset); } } }
//TODO: Currently this doesn't work on a folder that has no textures in it. public void LoadCustomFolderSprite(ICustomFolderInfo folder, string path) { if (string.IsNullOrEmpty(path)) { return; } var folderIconPath = Path.Combine(path, "folder.png"); if (!File.Exists(folderIconPath)) { folderIconPath = Path.Combine(path, "folder.jpg"); } if (!File.Exists(folderIconPath)) { folderIconPath = Path.Combine(path, "folder.jpeg"); } if (!File.Exists(folderIconPath)) { return; } // Assign new Sprite Sheet texture to the Sprite Asset. var texture = LoadTexture(folderIconPath); List <TMP_Sprite> spriteInfoList = new List <TMP_Sprite>(); TMP_Sprite sprite = new TMP_Sprite(); sprite.id = 0; sprite.name = Path.GetFileNameWithoutExtension(folderIconPath) ?? ""; sprite.hashCode = TMP_TextUtilities.GetSimpleHashCode(sprite.name); //// Attempt to extract Unicode value from name int unicode; int indexOfSeperator = sprite.name.IndexOf('-'); if (indexOfSeperator != -1) { unicode = TMP_TextUtilities.StringHexToInt(sprite.name.Substring(indexOfSeperator + 1)); } else { unicode = TMP_TextUtilities.StringHexToInt(sprite.name); } sprite.unicode = unicode; sprite.x = 0; sprite.y = 0; sprite.width = texture.width; sprite.height = texture.height; sprite.pivot = new Vector2(0.5f, 0.5f); sprite.xAdvance = sprite.width; sprite.scale = 1.0f; sprite.xOffset = 0 - (sprite.width * sprite.pivot.x); sprite.yOffset = sprite.height; spriteInfoList.Add(sprite); // Create new Sprite Asset using this texture TMP_SpriteAsset spriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>(); // Compute the hash code for the sprite asset. spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name); spriteAsset.spriteSheet = texture; spriteAsset.spriteInfoList = spriteInfoList; // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); folder.CustomSprite = spriteAsset; }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty property2 = property.FindPropertyRelative("id"); SerializedProperty serializedProperty = property.FindPropertyRelative("name"); SerializedProperty serializedProperty2 = property.FindPropertyRelative("hashCode"); SerializedProperty serializedProperty3 = property.FindPropertyRelative("unicode"); SerializedProperty serializedProperty4 = property.FindPropertyRelative("x"); SerializedProperty serializedProperty5 = property.FindPropertyRelative("y"); SerializedProperty serializedProperty6 = property.FindPropertyRelative("width"); SerializedProperty serializedProperty7 = property.FindPropertyRelative("height"); SerializedProperty property3 = property.FindPropertyRelative("xOffset"); SerializedProperty property4 = property.FindPropertyRelative("yOffset"); SerializedProperty property5 = property.FindPropertyRelative("xAdvance"); SerializedProperty property6 = property.FindPropertyRelative("scale"); SerializedProperty serializedProperty8 = property.FindPropertyRelative("sprite"); Texture spriteSheet = (property.serializedObject.targetObject as TMP_SpriteAsset).spriteSheet; if (spriteSheet == null) { Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject); return; } Vector2 vector = new Vector2(65f, 65f); if (serializedProperty6.floatValue >= serializedProperty7.floatValue) { vector.y = serializedProperty7.floatValue * vector.x / serializedProperty6.floatValue; position.y += (vector.x - vector.y) / 2f; } else { vector.x = serializedProperty6.floatValue * vector.y / serializedProperty7.floatValue; position.x += (vector.y - vector.x) / 2f; } GUI.DrawTextureWithTexCoords(texCoords: new Rect(serializedProperty4.floatValue / (float)spriteSheet.width, serializedProperty5.floatValue / (float)spriteSheet.height, serializedProperty6.floatValue / (float)spriteSheet.width, serializedProperty7.floatValue / (float)spriteSheet.height), position: new Rect(position.x + 5f, position.y, vector.x, vector.y), image: spriteSheet, alphaBlend: true); Rect rect = new Rect(position.x, position.y, position.width, 49f); rect.x += 70f; bool enabled = GUI.enabled; GUI.enabled = false; EditorGUIUtility.labelWidth = 30f; EditorGUI.PropertyField(new Rect(rect.x + 5f, rect.y, 65f, 18f), property2, new GUIContent("ID:")); GUI.enabled = enabled; EditorGUI.BeginChangeCheck(); EditorGUIUtility.labelWidth = 55f; GUI.SetNextControlName("Unicode Input"); string s = EditorGUI.TextField(new Rect(rect.x + 75f, rect.y, 105f, 18f), "Unicode:", serializedProperty3.intValue.ToString("X")); if (GUI.GetNameOfFocusedControl() == "Unicode Input") { char character = Event.current.character; if ((character < '0' || character > '9') && (character < 'a' || character > 'f') && (character < 'A' || character > 'F')) { Event.current.character = '\0'; } if (EditorGUI.EndChangeCheck()) { serializedProperty3.intValue = TMP_TextUtilities.StringToInt(s); property.serializedObject.ApplyModifiedProperties(); TMP_SpriteAsset tMP_SpriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset; tMP_SpriteAsset.UpdateLookupTables(); } } EditorGUIUtility.labelWidth = 45f; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(new Rect(rect.x + 185f, rect.y, rect.width - 260f, 18f), serializedProperty, new GUIContent("Name: " + serializedProperty.stringValue)); if (EditorGUI.EndChangeCheck()) { Sprite sprite = serializedProperty8.objectReferenceValue as Sprite; if (sprite != null) { sprite.name = serializedProperty.stringValue; } serializedProperty2.intValue = TMP_TextUtilities.GetSimpleHashCode(serializedProperty.stringValue); property.serializedObject.ApplyModifiedProperties(); } EditorGUIUtility.labelWidth = 30f; EditorGUIUtility.fieldWidth = 10f; float num = (rect.width - 75f) / 4f; EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 0f, rect.y + 22f, num - 5f, 18f), serializedProperty4, new GUIContent("X:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 1f, rect.y + 22f, num - 5f, 18f), serializedProperty5, new GUIContent("Y:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 2f, rect.y + 22f, num - 5f, 18f), serializedProperty6, new GUIContent("W:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 3f, rect.y + 22f, num - 5f, 18f), serializedProperty7, new GUIContent("H:")); EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 0f, rect.y + 44f, num - 5f, 18f), property3, new GUIContent("OX:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 1f, rect.y + 44f, num - 5f, 18f), property4, new GUIContent("OY:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 2f, rect.y + 44f, num - 5f, 18f), property5, new GUIContent("Adv.")); EditorGUI.PropertyField(new Rect(rect.x + 5f + num * 3f, rect.y + 44f, num - 5f, 18f), property6, new GUIContent("SF.")); if (!EditorGUI.EndChangeCheck()) { } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { //SerializedProperty prop_fileID = property.FindPropertyRelative("fileID"); SerializedProperty prop_id = property.FindPropertyRelative("id"); SerializedProperty prop_name = property.FindPropertyRelative("name"); SerializedProperty prop_hashCode = property.FindPropertyRelative("hashCode"); SerializedProperty prop_unicode = property.FindPropertyRelative("unicode"); SerializedProperty prop_x = property.FindPropertyRelative("x"); SerializedProperty prop_y = property.FindPropertyRelative("y"); SerializedProperty prop_width = property.FindPropertyRelative("width"); SerializedProperty prop_height = property.FindPropertyRelative("height"); SerializedProperty prop_xOffset = property.FindPropertyRelative("xOffset"); SerializedProperty prop_yOffset = property.FindPropertyRelative("yOffset"); SerializedProperty prop_xAdvance = property.FindPropertyRelative("xAdvance"); SerializedProperty prop_scale = property.FindPropertyRelative("scale"); SerializedProperty prop_sprite = property.FindPropertyRelative("sprite"); // Get a reference to the sprite texture Texture tex = (property.serializedObject.targetObject as TMP_SpriteAsset).spriteSheet; // Return if we don't have a texture assigned to the sprite asset. if (tex == null) { Debug.LogWarning("Please assign a valid Sprite Atlas texture to the [" + property.serializedObject.targetObject.name + "] Sprite Asset.", property.serializedObject.targetObject); return; } Vector2 spriteTexPosition = new Vector2(position.x, position.y); Vector2 spriteSize = new Vector2(65, 65); if (prop_width.floatValue >= prop_height.floatValue) { spriteSize.y = prop_height.floatValue * spriteSize.x / prop_width.floatValue; spriteTexPosition.y += (spriteSize.x - spriteSize.y) / 2; } else { spriteSize.x = prop_width.floatValue * spriteSize.y / prop_height.floatValue; spriteTexPosition.x += (spriteSize.y - spriteSize.x) / 2; } // Compute the normalized texture coordinates Rect texCoords = new Rect(prop_x.floatValue / tex.width, prop_y.floatValue / tex.height, prop_width.floatValue / tex.width, prop_height.floatValue / tex.height); GUI.DrawTextureWithTexCoords(new Rect(spriteTexPosition.x + 5, spriteTexPosition.y + 2.5f, spriteSize.x, spriteSize.y), tex, texCoords, true); // We get Rect since a valid position may not be provided by the caller. Rect rect = new Rect(position.x, position.y, position.width, 49); rect.x += 70; bool isEnabled = GUI.enabled; GUI.enabled = false; EditorGUIUtility.labelWidth = 30f; EditorGUI.PropertyField(new Rect(rect.x + 5f, rect.y, 65f, 18), prop_id, new GUIContent("ID:")); GUI.enabled = isEnabled; EditorGUI.BeginChangeCheck(); EditorGUIUtility.labelWidth = 55f; GUI.SetNextControlName("Unicode Input"); string unicode = EditorGUI.TextField(new Rect(rect.x + 75f, rect.y, 105, 18), "Unicode:", prop_unicode.intValue.ToString("X")); if (GUI.GetNameOfFocusedControl() == "Unicode Input") { //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F')) { Event.current.character = '\0'; } if (EditorGUI.EndChangeCheck()) { prop_unicode.intValue = TMP_TextUtilities.StringToInt(unicode); property.serializedObject.ApplyModifiedProperties(); TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset; spriteAsset.UpdateLookupTables(); } } EditorGUIUtility.labelWidth = 45f; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(new Rect(rect.x + 185f, rect.y, rect.width - 260, 18), prop_name, new GUIContent("Name: " + prop_name.stringValue)); if (EditorGUI.EndChangeCheck()) { Sprite sprite = prop_sprite.objectReferenceValue as Sprite; if (sprite != null) { sprite.name = prop_name.stringValue; } // Recompute hashCode for new name prop_hashCode.intValue = TMP_TextUtilities.GetSimpleHashCode(prop_name.stringValue); // Check to make sure for duplicates property.serializedObject.ApplyModifiedProperties(); // Dictionary needs to be updated since HashCode has changed. //TMP_StyleSheet.Instance.LoadStyleDictionary(); } EditorGUIUtility.labelWidth = 30f; EditorGUIUtility.fieldWidth = 10f; //GUI.enabled = false; float width = (rect.width - 75f) / 4; EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 0, rect.y + 22, width - 5f, 18), prop_x, new GUIContent("X:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 1, rect.y + 22, width - 5f, 18), prop_y, new GUIContent("Y:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 2, rect.y + 22, width - 5f, 18), prop_width, new GUIContent("W:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 3, rect.y + 22, width - 5f, 18), prop_height, new GUIContent("H:")); //GUI.enabled = true; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 0, rect.y + 44, width - 5f, 18), prop_xOffset, new GUIContent("OX:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 1, rect.y + 44, width - 5f, 18), prop_yOffset, new GUIContent("OY:")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 2, rect.y + 44, width - 5f, 18), prop_xAdvance, new GUIContent("Adv.")); EditorGUI.PropertyField(new Rect(rect.x + 5f + width * 3, rect.y + 44, width - 5f, 18), prop_scale, new GUIContent("SF.")); if (EditorGUI.EndChangeCheck()) { //Sprite sprite = prop_sprite.objectReferenceValue as Sprite; //sprite = Sprite.Create(sprite.texture, sprite.rect, new Vector2(0.1f, 0.8f)); //prop_sprite.objectReferenceValue = sprite; //Debug.Log(sprite.bounds); } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty prop_SpriteName = property.FindPropertyRelative("m_Name"); SerializedProperty prop_SpriteNameHashCode = property.FindPropertyRelative("m_HashCode"); SerializedProperty prop_SpriteUnicode = property.FindPropertyRelative("m_Unicode"); SerializedProperty prop_SpriteGlyphIndex = property.FindPropertyRelative("m_GlyphIndex"); SerializedProperty prop_SpriteScale = property.FindPropertyRelative("m_Scale"); GUIStyle style = new GUIStyle(EditorStyles.label); style.richText = true; EditorGUIUtility.labelWidth = 40f; EditorGUIUtility.fieldWidth = 50; Rect rect = new Rect(position.x + 60, position.y, position.width, 49); // Display non-editable fields if (GUI.enabled == false) { // Sprite Character Index int spriteCharacterIndex; int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex); EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style); EditorGUI.LabelField(new Rect(rect.x + 75f, rect.y, 120f, 18), new GUIContent("Unicode: <color=#FFFF80>0x" + prop_SpriteUnicode.intValue.ToString("X") + "</color>"), style); EditorGUI.LabelField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), new GUIContent("Name: <color=#FFFF80>" + prop_SpriteName.stringValue + "</color>"), style); EditorGUI.LabelField(new Rect(rect.x, rect.y + 18, 120, 18), new GUIContent("Glyph ID: <color=#FFFF80>" + prop_SpriteGlyphIndex.intValue + "</color>"), style); // Draw Sprite Glyph (if exists) DrawSpriteGlyph(position, property); EditorGUI.LabelField(new Rect(rect.x, rect.y + 36, 80, 18), new GUIContent("Scale: <color=#FFFF80>" + prop_SpriteScale.floatValue + "</color>"), style); } else // Display editable fields { // Get a reference to the underlying Sprite Asset TMP_SpriteAsset spriteAsset = property.serializedObject.targetObject as TMP_SpriteAsset; // Sprite Character Index int spriteCharacterIndex; int.TryParse(property.displayName.Split(' ')[1], out spriteCharacterIndex); EditorGUI.LabelField(new Rect(rect.x, rect.y, 75f, 18), new GUIContent("Index: <color=#FFFF80>" + spriteCharacterIndex + "</color>"), style); EditorGUIUtility.labelWidth = 55f; GUI.SetNextControlName("Unicode Input"); EditorGUI.BeginChangeCheck(); string unicode = EditorGUI.DelayedTextField(new Rect(rect.x + 75f, rect.y, 120, 18), "Unicode:", prop_SpriteUnicode.intValue.ToString("X")); if (GUI.GetNameOfFocusedControl() == "Unicode Input") { //Filter out unwanted characters. char chr = Event.current.character; if ((chr < '0' || chr > '9') && (chr < 'a' || chr > 'f') && (chr < 'A' || chr > 'F')) { Event.current.character = '\0'; } } if (EditorGUI.EndChangeCheck()) { // Update Unicode value prop_SpriteUnicode.intValue = TMP_TextUtilities.StringHexToInt(unicode); spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } EditorGUIUtility.labelWidth = 41f; EditorGUI.BeginChangeCheck(); EditorGUI.DelayedTextField(new Rect(rect.x + 195f, rect.y, rect.width - 255, 18), prop_SpriteName, new GUIContent("Name:")); if (EditorGUI.EndChangeCheck()) { // Recompute hashCode for new name prop_SpriteNameHashCode.intValue = TMP_TextUtilities.GetSimpleHashCode(prop_SpriteName.stringValue); spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } EditorGUIUtility.labelWidth = 59f; EditorGUI.BeginChangeCheck(); EditorGUI.DelayedIntField(new Rect(rect.x, rect.y + 18, 100, 18), prop_SpriteGlyphIndex, new GUIContent("Glyph ID:")); if (EditorGUI.EndChangeCheck()) { spriteAsset.m_IsSpriteAssetLookupTablesDirty = true; } // Draw Sprite Glyph (if exists) DrawSpriteGlyph(position, property); int glyphIndex = prop_SpriteGlyphIndex.intValue; // Reset glyph selection if new character has been selected. if (GUI.enabled && m_GlyphSelectedForEditing != glyphIndex) { m_GlyphSelectedForEditing = -1; } // Display button to edit the glyph data. if (GUI.Button(new Rect(rect.x + 120, rect.y + 18, 75, 18), new GUIContent("Edit Glyph"))) { if (m_GlyphSelectedForEditing == -1) { m_GlyphSelectedForEditing = glyphIndex; } else { m_GlyphSelectedForEditing = -1; } // Button clicks should not result in potential change. GUI.changed = false; } // Show the glyph property drawer if selected if (glyphIndex == m_GlyphSelectedForEditing && GUI.enabled) { if (spriteAsset != null) { // Lookup glyph and draw glyph (if available) int elementIndex = spriteAsset.spriteGlyphTable.FindIndex(item => item.index == glyphIndex); if (elementIndex != -1) { // Get a reference to the Sprite Glyph Table SerializedProperty prop_SpriteGlyphTable = property.serializedObject.FindProperty("m_SpriteGlyphTable"); SerializedProperty prop_SpriteGlyph = prop_SpriteGlyphTable.GetArrayElementAtIndex(elementIndex); SerializedProperty prop_GlyphMetrics = prop_SpriteGlyph.FindPropertyRelative("m_Metrics"); SerializedProperty prop_GlyphRect = prop_SpriteGlyph.FindPropertyRelative("m_GlyphRect"); Rect newRect = EditorGUILayout.GetControlRect(false, 115); EditorGUI.DrawRect(new Rect(newRect.x + 62, newRect.y - 20, newRect.width - 62, newRect.height - 5), new Color(0.1f, 0.1f, 0.1f, 0.45f)); EditorGUI.DrawRect(new Rect(newRect.x + 63, newRect.y - 19, newRect.width - 64, newRect.height - 7), new Color(0.3f, 0.3f, 0.3f, 0.8f)); // Display GlyphRect newRect.x += 65; newRect.y -= 18; newRect.width += 5; EditorGUI.PropertyField(newRect, prop_GlyphRect); // Display GlyphMetrics newRect.y += 45; EditorGUI.PropertyField(newRect, prop_GlyphMetrics); rect.y += 120; } } } EditorGUIUtility.labelWidth = 39f; EditorGUI.PropertyField(new Rect(rect.x, rect.y + 36, 80, 18), prop_SpriteScale, new GUIContent("Scale:")); } }
public static IEnumerator ProcessAsync(string text) { didProcessAsync = false; if (rootEmojiAsset == null) { yield break; } if (string.IsNullOrEmpty(text)) { yield break; } List <string> detectedEmojis = new List <string>(); string emojiText = null; while ((emojiText = EmojiTexture.GetFirstEmoji(text)) != null) { text = text.Substring(text.IndexOf(emojiText, System.StringComparison.Ordinal)); if (!string.IsNullOrEmpty(emojiText)) { int spriteIndex = -1; TMP_SpriteAsset spriteAsset = TMP_SpriteAsset .SearchForSpriteByUnicode(rootEmojiAsset, char.ConvertToUtf32(emojiText, 0), true, out spriteIndex); if (spriteAsset == null) { detectedEmojis.Add(emojiText); } text = text.Substring(emojiText.Length); } else { break; } } if (detectedEmojis.Count > 0) { yield return(GithubHelper.Initialize()); } foreach (var detectedEmoji in detectedEmojis) { string hex = char.ConvertToUtf32(detectedEmoji, 0).ToString("X"); if (GithubHelper.IsValid(hex)) { yield return(emojiTexture.SetGithubEmoji(hex)); if (emojiTexture.didDownloadTexture) { PushSprite(emojiTexture); didProcessAsync = true; } } } //If the texture has unsaved changes, we apply them here //And make it non readable if it is full if (textureNeedsApply) { var makeNoLongerReadable = currentEmojiIndex == SHEET_TILES * SHEET_TILES; ((Texture2D)currentEmojiAsset.spriteSheet).Apply(false, makeNoLongerReadable); textureNeedsApply = false; } }
public static void CreateTextMeshProObjectPerform() { Object target = Selection.activeObject; // Make sure the selection is a texture. if (target == null || target.GetType() != typeof(Texture2D)) { return; } Texture2D sourceTex = target as Texture2D; // Get the path to the selected texture. string filePathWithName = AssetDatabase.GetAssetPath(sourceTex); string fileNameWithExtension = Path.GetFileName(filePathWithName); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName); string filePath = filePathWithName.Replace(fileNameWithExtension, ""); // Check if Sprite Asset already exists TMP_SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(filePath + fileNameWithoutExtension + ".asset", typeof(TMP_SpriteAsset)) as TMP_SpriteAsset; bool isNewAsset = spriteAsset == null ? true : false; if (isNewAsset) { // Create new Sprite Asset using this texture spriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>(); AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset"); // Assign new Sprite Sheet texture to the Sprite Asset. spriteAsset.spriteSheet = sourceTex; spriteAsset.spriteInfoList = GetSpriteInfo(sourceTex); //spriteAsset.UpdateSpriteArray(sourceTex); //spriteSheet.hideFlags = HideFlags.HideInHierarchy; //AssetDatabase.AddObjectToAsset(spriteSheet, spriteAsset); //spriteAsset.spriteSheetWidth = sourceTex.width; //spriteAsset.spriteSheetHeight = sourceTex.height; } else { spriteAsset.spriteInfoList = UpdateSpriteInfo(spriteAsset); } // Get the Sprites contained in the Sprite Sheet EditorUtility.SetDirty(spriteAsset); //spriteAsset.sprites = sprites; // Set source texture back to Not Readable. //texImporter.isReadable = false; AssetDatabase.SaveAssets(); //AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version. //AssetDatabase.Refresh(); }
// Update existing SpriteInfo private static List<TMP_Sprite> UpdateSpriteInfo(TMP_SpriteAsset spriteAsset) { //Debug.Log("Updating Sprite Asset."); string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); // Get all the Sprites sorted Left to Right / Top to Bottom Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); for (int i = 0; i < sprites.Length; i++) { Sprite sprite = sprites[i]; // Check if sprite already exists in the SpriteInfoList int index = -1; if (spriteAsset.spriteInfoList[i].sprite != null) index = spriteAsset.spriteInfoList.FindIndex(item => item.sprite.GetInstanceID() == sprite.GetInstanceID()); // Use existing SpriteInfo if it already exists TMP_Sprite spriteInfo = index == -1 ? new TMP_Sprite() : spriteAsset.spriteInfoList[index]; Rect spriteRect = sprite.rect; if (spriteInfo.name != sprite.name) { // Preserve the existing sprite name. sprite.name = spriteInfo.name; //spriteInfo.name = sprite.name; spriteInfo.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteInfo.name); } spriteInfo.x = spriteRect.x; spriteInfo.y = spriteRect.y; spriteInfo.width = spriteRect.width; spriteInfo.height = spriteRect.height; // Get Sprite Pivot Vector2 pivot = new Vector2(0 - (sprite.bounds.min.x) / (sprite.bounds.extents.x * 2), 0 - (sprite.bounds.min.y) / (sprite.bounds.extents.y * 2)); // The position of the pivot influences the Offset position. spriteInfo.pivot = new Vector2(0 - pivot.x * spriteRect.width, spriteRect.height - pivot.y * spriteRect.height); if (index == -1) { // Find the next available index for this Sprite int[] ids = spriteAsset.spriteInfoList.Select(item => item.id).ToArray(); int id = 0; for (int j = 0; j < ids.Length; j++ ) { if (ids[0] != 0) break; if (j > 0 && (ids[j] - ids[j - 1]) > 1) { id = ids[j - 1] + 1; break; } id = j + 1; } //spriteInfo.fileID = fileID; spriteInfo.id = id; spriteInfo.xAdvance = spriteRect.width; spriteInfo.scale = 1.0f; spriteInfo.xOffset = spriteInfo.pivot.x; spriteInfo.yOffset = spriteInfo.pivot.y; spriteAsset.spriteInfoList.Add(spriteInfo); } else { spriteAsset.spriteInfoList[index] = spriteInfo; } } return spriteAsset.spriteInfoList; }
internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset) { // Get a list of all the sprites contained in the texture referenced by the sprite asset. // This only works if the texture is set to sprite mode. string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); if (string.IsNullOrEmpty(filePath)) { return; } // Get all the Sprites sorted Left to Right / Top to Bottom Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); List <TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable; // Finding available glyph indexes to insert new glyphs into. var tempGlyphTable = spriteGlyphTable.OrderBy(glyph => glyph.index).ToList(); List <uint> availableGlyphIndexes = new List <uint>(); int elementIndex = 0; for (uint i = 0; i < tempGlyphTable[tempGlyphTable.Count - 1].index; i++) { uint currentElementIndex = tempGlyphTable[elementIndex].index; if (i == currentElementIndex) { elementIndex += 1; } else { availableGlyphIndexes.Add(i); } } // Iterate over each of the sprites in the texture to try to match them to existing sprites in the sprite asset. for (int i = 0; i < sprites.Length; i++) { int id = sprites[i].GetInstanceID(); int glyphIndex = spriteGlyphTable.FindIndex(item => item.sprite.GetInstanceID() == id); if (glyphIndex == -1) { // Add new Sprite Glyph to the table Sprite sprite = sprites[i]; TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph(); // Get available glyph index if (availableGlyphIndexes.Count > 0) { spriteGlyph.index = availableGlyphIndexes[0]; availableGlyphIndexes.RemoveAt(0); } else { spriteGlyph.index = (uint)spriteGlyphTable.Count; } spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width); spriteGlyph.glyphRect = new GlyphRect(sprite.rect); spriteGlyph.scale = 1.0f; spriteGlyph.sprite = sprite; spriteGlyphTable.Add(spriteGlyph); TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph); spriteCharacter.name = sprite.name; spriteCharacter.scale = 1.0f; spriteAsset.spriteCharacterTable.Add(spriteCharacter); } else { // Look for changes in existing Sprite Glyph Sprite sprite = sprites[i]; TMP_SpriteGlyph spriteGlyph = spriteGlyphTable[glyphIndex]; // We only update changes to the sprite position / glyph rect. if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) { spriteGlyph.glyphRect = new GlyphRect(sprite.rect); } } } // Sort glyph table by glyph index spriteAsset.SortGlyphTable(); spriteAsset.UpdateLookupTables(); TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset); }
// Update existing SpriteInfo private static List <TMP_Sprite> UpdateSpriteInfo(TMP_SpriteAsset spriteAsset) { //Debug.Log("Updating Sprite Asset."); string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); // Get all the Sprites sorted Left to Right / Top to Bottom Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).OrderByDescending(x => x.rect.y).ThenBy(x => x.rect.x).ToArray(); for (int i = 0; i < sprites.Length; i++) { Sprite sprite = sprites[i]; // Check if the sprite is already contained in the SpriteInfoList int index = -1; if (spriteAsset.spriteInfoList.Count > i && spriteAsset.spriteInfoList[i].sprite != null) { index = spriteAsset.spriteInfoList.FindIndex(item => item.sprite.GetInstanceID() == sprite.GetInstanceID()); } // Use existing SpriteInfo if it already exists TMP_Sprite spriteInfo = index == -1 ? new TMP_Sprite() : spriteAsset.spriteInfoList[index]; Rect spriteRect = sprite.rect; spriteInfo.x = spriteRect.x; spriteInfo.y = spriteRect.y; spriteInfo.width = spriteRect.width; spriteInfo.height = spriteRect.height; // Get Sprite Pivot Vector2 pivot = new Vector2(0 - (sprite.bounds.min.x) / (sprite.bounds.extents.x * 2), 0 - (sprite.bounds.min.y) / (sprite.bounds.extents.y * 2)); // The position of the pivot influences the Offset position. spriteInfo.pivot = new Vector2(0 - pivot.x * spriteRect.width, spriteRect.height - pivot.y * spriteRect.height); if (index == -1) { // Find the next available index for this Sprite int[] ids = spriteAsset.spriteInfoList.Select(item => item.id).ToArray(); int id = 0; for (int j = 0; j < ids.Length; j++) { if (ids[0] != 0) { break; } if (j > 0 && (ids[j] - ids[j - 1]) > 1) { id = ids[j - 1] + 1; break; } id = j + 1; } spriteInfo.sprite = sprite; spriteInfo.name = sprite.name; spriteInfo.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteInfo.name); spriteInfo.id = id; spriteInfo.xAdvance = spriteRect.width; spriteInfo.scale = 1.0f; spriteInfo.xOffset = spriteInfo.pivot.x; spriteInfo.yOffset = spriteInfo.pivot.y; spriteAsset.spriteInfoList.Add(spriteInfo); // Sort the Sprites by ID spriteAsset.spriteInfoList = spriteAsset.spriteInfoList.OrderBy(s => s.id).ToList(); } else { spriteAsset.spriteInfoList[index] = spriteInfo; } } return(spriteAsset.spriteInfoList); }
static Dictionary <TMP_SpriteAsset, HashSet <string> > s_fastLookupPath = new Dictionary <TMP_SpriteAsset, HashSet <string> >(); //this will cache will save the path of each character in sequence, so for every iteration we can check if we need to continue #endregion #region Emoji Search Engine Functions /// <summary> /// Try parse text converting to supported EmojiSequence format (all char sequences will be replaced to <sprite=index>) /// </summary> /// <param name="p_spriteAsset"></param> /// <param name="text"></param> /// <returns></returns> public static bool ParseEmojiCharSequence(TMP_SpriteAsset p_spriteAsset, ref string p_text) { bool v_changed = false; TryUpdateSequenceLookupTable(p_spriteAsset); if (!string.IsNullOrEmpty(p_text)) { var v_mainSpriteAsset = p_spriteAsset == null ? TMPro.TMP_Settings.defaultSpriteAsset : p_spriteAsset; var v_fastLookupPath = v_mainSpriteAsset != null && s_fastLookupPath.ContainsKey(v_mainSpriteAsset) ? s_fastLookupPath[v_mainSpriteAsset] : new HashSet <string>(); var v_lookupTableSequences = v_mainSpriteAsset != null && s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) ? s_lookupTableSequences[v_mainSpriteAsset] : new Dictionary <string, string>(); if (v_lookupTableSequences == null || v_lookupTableSequences.Count == 0) { return(false); } System.Text.StringBuilder sb = new System.Text.StringBuilder(); //Eficient way to check characters for (int i = 0; i < p_text.Length; i++) { int v_endCounter = i; System.Text.StringBuilder v_auxSequence = new System.Text.StringBuilder(); //Look for sequences in fastLookupPath while (p_text.Length > v_endCounter && (v_endCounter == i || v_fastLookupPath.Contains(v_auxSequence.ToString())) ) { //We must skip variant selectors (if found it) v_auxSequence.Append(p_text[v_endCounter]); v_endCounter++; } //Remove last added guy (the previous one is the correct) if (v_auxSequence.Length > 0 && !v_fastLookupPath.Contains(v_auxSequence.ToString())) { v_auxSequence.Remove(v_auxSequence.Length - 1, 1); } var v_sequence = v_auxSequence.Length > 0 ? v_auxSequence.ToString() : ""; //Found a sequence, add it instead add the character if (v_sequence.Length > 0 && v_lookupTableSequences.ContainsKey(v_sequence)) { v_changed = true; //Changed Index to Sprite Name to prevent erros when looking at fallbacks sb.Append(string.Format("<sprite name=\"{0}\">", v_lookupTableSequences[v_sequence])); i += (v_sequence.Length - 1); //jump checked characters } //add the char (normal character) else { sb.Append(p_text[i]); } } if (v_changed) { p_text = sb.ToString(); } } return(v_changed); }
/// <summary> /// Cache all sequences in a lookuptable (and in a fastpath) found in SpriteAsset /// This Lookuptable will return the Sprite Index of the Emoji in SpriteAsset (the key will be the char sequence that will be used as replacement of old unicode format) /// /// The sequence will be the name of the TMP_Sprite in UTF32 or UTF16 HEX format separeted by '-' for each character (see below the example) /// Ex: 0023-fe0f-20e3.png /// </summary> /// <param name="p_spriteAsset"> The sprite asset used to cache the sequences</param> /// <param name="p_forceUpdate"> force update the lookup table of this SpriteAsset</param> /// <returns>true if lookup table changed</returns> public static bool TryUpdateSequenceLookupTable(TMP_SpriteAsset p_spriteAsset, bool p_forceUpdate = false) { var v_mainSpriteAsset = p_spriteAsset == null ? TMPro.TMP_Settings.defaultSpriteAsset : p_spriteAsset; if (v_mainSpriteAsset != null && (!s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) || s_lookupTableSequences[v_mainSpriteAsset] == null || p_forceUpdate)) { //Init FastlookupPath if (v_mainSpriteAsset != null && (!s_fastLookupPath.ContainsKey(v_mainSpriteAsset) || s_fastLookupPath[v_mainSpriteAsset] == null)) { s_fastLookupPath[v_mainSpriteAsset] = new HashSet <string>(); } var v_fastLookupPath = v_mainSpriteAsset != null && s_fastLookupPath.ContainsKey(v_mainSpriteAsset) ? s_fastLookupPath[v_mainSpriteAsset] : new HashSet <string>(); v_fastLookupPath.Clear(); //Init Lookup Table if (v_mainSpriteAsset != null && (!s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) || s_lookupTableSequences[v_mainSpriteAsset] == null)) { s_lookupTableSequences[v_mainSpriteAsset] = new Dictionary <string, string>(); } var v_lookupTableSequences = v_mainSpriteAsset != null && s_lookupTableSequences.ContainsKey(v_mainSpriteAsset) ? s_lookupTableSequences[v_mainSpriteAsset] : new Dictionary <string, string>(); v_lookupTableSequences.Clear(); List <TMPro.TMP_SpriteAsset> v_spriteAssetsChecked = new List <TMPro.TMP_SpriteAsset>(); v_spriteAssetsChecked.Add(v_mainSpriteAsset); //Add the main sprite asset if (TMPro.TMP_Settings.defaultSpriteAsset != null && !v_spriteAssetsChecked.Contains(TMPro.TMP_Settings.defaultSpriteAsset)) { v_spriteAssetsChecked.Add(TMPro.TMP_Settings.defaultSpriteAsset); } //Check in all spriteassets (and fallbacks) for (int i = 0; i < v_spriteAssetsChecked.Count; i++) { var v_spriteAsset = v_spriteAssetsChecked[i]; if (v_spriteAsset != null) { //Check all sprites in this sprite asset for (int j = 0; j < v_spriteAsset.spriteInfoList.Count; j++) { var v_element = v_spriteAsset.spriteInfoList[j]; if (v_element == null || string.IsNullOrEmpty(v_element.name) || !v_element.name.Contains("-")) { continue; } var v_elementName = BuildNameInEmojiSurrogateFormat(v_element.name); var v_unicodeX8 = v_element.unicode.ToString("X8"); //Check for elements that Unicode is different from Name if (!string.IsNullOrEmpty(v_elementName) && !string.Equals(v_elementName, v_unicodeX8, System.StringComparison.InvariantCultureIgnoreCase)) { var v_tableStringBuilder = new System.Text.StringBuilder(); for (int k = 0; k < v_elementName.Length; k += 8) { var v_hexUTF32 = v_elementName.Substring(k, Mathf.Min(v_elementName.Length - k, 8)); #if UNITY_2018_3_OR_NEWER var v_intValue = TMPro.TMP_TextUtilities.StringHexToInt(v_hexUTF32); #else var v_intValue = TMPro.TMP_TextUtilities.StringToInt(v_hexUTF32); #endif //Not a surrogate and is valid UTF32 (conditions to use char.ConvertFromUtf32 function) if (v_intValue > 0x000000 && v_intValue < 0x10ffff && (v_intValue < 0x00d800 || v_intValue > 0x00dfff)) { var v_UTF16Surrogate = char.ConvertFromUtf32(v_intValue); if (!string.IsNullOrEmpty(v_UTF16Surrogate)) { //Add chars into cache (we must include the both char paths in fastLookupPath) foreach (var v_surrogateChar in v_UTF16Surrogate) { v_tableStringBuilder.Append(v_surrogateChar); //Add current path to lookup fast path v_fastLookupPath.Add(v_tableStringBuilder.ToString()); } } } //Split into two chars (we failed to match conditions of char.ConvertFromUtf32 so we must split into two UTF16 chars) else { for (int l = 0; l < v_hexUTF32.Length; l += 4) { var v_hexUTF16 = v_hexUTF32.Substring(l, Mathf.Min(v_hexUTF32.Length - l, 4)); #if UNITY_2018_3_OR_NEWER var v_charValue = (char)TMPro.TMP_TextUtilities.StringHexToInt(v_hexUTF16); #else var v_charValue = (char)TMPro.TMP_TextUtilities.StringToInt(v_hexUTF16); #endif v_tableStringBuilder.Append(v_charValue); //Add current path to lookup fast path v_fastLookupPath.Add(v_tableStringBuilder.ToString()); } } } var v_tableKey = v_tableStringBuilder.ToString(); //Add key as sequence in lookupTable if (!string.IsNullOrEmpty(v_tableKey) && !v_lookupTableSequences.ContainsKey(v_tableKey)) { v_lookupTableSequences[v_tableKey] = v_element.name; //j; } } } //Add Fallbacks (before the next sprite asset and after this sprite asset) for (int k = v_spriteAsset.fallbackSpriteAssets.Count - 1; k >= 0; k--) { var v_fallback = v_spriteAsset.fallbackSpriteAssets[k]; if (v_fallback != null && !v_spriteAssetsChecked.Contains(v_fallback)) { v_spriteAssetsChecked.Insert(i + 1, v_fallback); } } } } return(true); } return(false); }
internal static void UpdateSpriteAsset(TMP_SpriteAsset spriteAsset) { // Get a list of all the sprites contained in the texture referenced by the sprite asset. // This only works if the texture is set to sprite mode. string filePath = AssetDatabase.GetAssetPath(spriteAsset.spriteSheet); if (string.IsNullOrEmpty(filePath)) { return; } // Get all the sprites defined in the sprite sheet texture referenced by this sprite asset. Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(filePath).Select(x => x as Sprite).Where(x => x != null).ToArray(); // Return if sprite sheet texture does not have any sprites defined in it. if (sprites.Length == 0) { Debug.Log("Sprite Asset <color=#FFFF80>[" + spriteAsset.name + "]</color>'s atlas texture does not appear to have any sprites defined in it. Use the Unity Sprite Editor to define sprites for this texture.", spriteAsset.spriteSheet); return; } List <TMP_SpriteGlyph> spriteGlyphTable = spriteAsset.spriteGlyphTable; // Find available glpyh indexes uint[] existingGlyphIndexes = spriteGlyphTable.Select(x => x.index).ToArray(); List <uint> availableGlyphIndexes = new List <uint>(); uint lastGlyphIndex = existingGlyphIndexes.Length > 0 ? existingGlyphIndexes.Last() : 0; int elementIndex = 0; for (uint i = 0; i < lastGlyphIndex; i++) { uint existingGlyphIndex = existingGlyphIndexes[elementIndex]; if (i == existingGlyphIndex) { elementIndex += 1; } else { availableGlyphIndexes.Add(i); } } // Iterate over sprites contained in the updated sprite sheet to identify new and / or modified sprites. for (int i = 0; i < sprites.Length; i++) { Sprite sprite = sprites[i]; // Check if current sprites is already contained in the sprite glyph table of the sprite asset. TMP_SpriteGlyph spriteGlyph = spriteGlyphTable.FirstOrDefault(x => x.sprite == sprite); if (spriteGlyph != null) { // update existing sprite glyph if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) { spriteGlyph.glyphRect = new GlyphRect(sprite.rect); } } else { TMP_SpriteCharacter spriteCharacter; // Check if this sprite potentially exists under the same name in the sprite character table. if (spriteAsset.spriteCharacterTable != null && spriteAsset.spriteCharacterTable.Count > 0) { spriteCharacter = spriteAsset.spriteCharacterTable.FirstOrDefault(x => x.name == sprite.name); spriteGlyph = spriteCharacter != null ? spriteGlyphTable[(int)spriteCharacter.glyphIndex] : null; if (spriteGlyph != null) { // Update sprite reference and data spriteGlyph.sprite = sprite; if (spriteGlyph.glyphRect.x != sprite.rect.x || spriteGlyph.glyphRect.y != sprite.rect.y || spriteGlyph.glyphRect.width != sprite.rect.width || spriteGlyph.glyphRect.height != sprite.rect.height) { spriteGlyph.glyphRect = new GlyphRect(sprite.rect); } } } // Add new Sprite Glyph to the table spriteGlyph = new TMP_SpriteGlyph(); // Get available glyph index if (availableGlyphIndexes.Count > 0) { spriteGlyph.index = availableGlyphIndexes[0]; availableGlyphIndexes.RemoveAt(0); } else { spriteGlyph.index = (uint)spriteGlyphTable.Count; } spriteGlyph.metrics = new GlyphMetrics(sprite.rect.width, sprite.rect.height, -sprite.pivot.x, sprite.rect.height - sprite.pivot.y, sprite.rect.width); spriteGlyph.glyphRect = new GlyphRect(sprite.rect); spriteGlyph.scale = 1.0f; spriteGlyph.sprite = sprite; spriteGlyphTable.Add(spriteGlyph); spriteCharacter = new TMP_SpriteCharacter(0xFFFE, spriteGlyph); spriteCharacter.name = sprite.name; spriteCharacter.scale = 1.0f; spriteAsset.spriteCharacterTable.Add(spriteCharacter); } } // Update Sprite Character Table to replace unicode 0x0 by 0xFFFE for (int i = 0; i < spriteAsset.spriteCharacterTable.Count; i++) { TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[i]; if (spriteCharacter.unicode == 0) { spriteCharacter.unicode = 0xFFFE; } } // Sort glyph table by glyph index spriteAsset.SortGlyphTable(); spriteAsset.UpdateLookupTables(); TMPro_EventManager.ON_SPRITE_ASSET_PROPERTY_CHANGED(true, spriteAsset); }
public static void CreateSpriteAsset() { Object target = Selection.activeObject; if (target == null || target.GetType() != typeof(Texture2D)) // && target.GetType() != typeof(SpriteAtlas))) { Debug.LogWarning("A texture must first be selected in order to create a TextMesh Pro Sprite Asset."); return; } // Get the path to the selected asset. string filePathWithName = AssetDatabase.GetAssetPath(target); string fileNameWithExtension = Path.GetFileName(filePathWithName); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName); string filePath = filePathWithName.Replace(fileNameWithExtension, ""); // Create new Sprite Asset TMP_SpriteAsset spriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>(); AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset"); spriteAsset.version = "1.1.0"; // Compute the hash code for the sprite asset. spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name); List <TMP_SpriteGlyph> spriteGlyphTable = new List <TMP_SpriteGlyph>(); List <TMP_SpriteCharacter> spriteCharacterTable = new List <TMP_SpriteCharacter>(); if (target.GetType() == typeof(Texture2D)) { Texture2D sourceTex = target as Texture2D; // Assign new Sprite Sheet texture to the Sprite Asset. spriteAsset.spriteSheet = sourceTex; PopulateSpriteTables(sourceTex, ref spriteCharacterTable, ref spriteGlyphTable); spriteAsset.spriteCharacterTable = spriteCharacterTable; spriteAsset.spriteGlyphTable = spriteGlyphTable; // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); } else if (target.GetType() == typeof(SpriteAtlas)) { //SpriteAtlas spriteAtlas = target as SpriteAtlas; //PopulateSpriteTables(spriteAtlas, ref spriteCharacterTable, ref spriteGlyphTable); //spriteAsset.spriteCharacterTable = spriteCharacterTable; //spriteAsset.spriteGlyphTable = spriteGlyphTable; //spriteAsset.spriteSheet = spriteGlyphTable[0].sprite.texture; //// Add new default material for sprite asset. //AddDefaultMaterial(spriteAsset); } // Update Lookup tables. spriteAsset.UpdateLookupTables(); // Get the Sprites contained in the Sprite Sheet EditorUtility.SetDirty(spriteAsset); //spriteAsset.sprites = sprites; // Set source texture back to Not Readable. //texImporter.isReadable = false; AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version. //AssetDatabase.Refresh(); }
/// <summary> /// 更新图集数据 /// </summary> private void ApplySpriteAssetData() { if (cacheSpriteGlyphs == null || cacheSpriteGlyphs.Count == 0 || cacheSpriteCharacters == null || cacheSpriteCharacters.Count == 0) { Debug.LogError("无缓存数据"); } //1.解析新的tpsheet string str = File.ReadAllText(arrangeIconAtlasTpsheetFilePath); string[] strArr = str.Split('\n'); //以Name为key的GlyphRect数据 Dictionary <string, GlyphRect> glyphRectDic = new Dictionary <string, GlyphRect>(); foreach (var item in strArr) { if (item.StartsWith("#") || item.StartsWith(":") || string.IsNullOrEmpty(item) || item.StartsWith("\r")) { continue; } string[] strArr2 = item.Split(';'); int x = int.Parse(strArr2[1]); int y = int.Parse(strArr2[2]); int w = int.Parse(strArr2[3]); int h = int.Parse(strArr2[4]); GlyphRect rect = new GlyphRect(x, y, w, h); glyphRectDic.Add(strArr2[0], rect); } //1.1获取新的数据,主要使用GlyphMetrics Texture texture = AssetDatabase.LoadAssetAtPath <Texture>(AtlasPngPath); List <TMP_SpriteCharacter> newSpriteCharacters = new List <TMP_SpriteCharacter>(); List <TMP_SpriteGlyph> newSpriteGlyphs = new List <TMP_SpriteGlyph>(); PopulateSpriteTables(texture, ref newSpriteCharacters, ref newSpriteGlyphs); //2.更新Cache //2.1 cacheSpriteGlyphs //2.2 cacheSpriteCharacters if (cacheSpriteGlyphs != null && cacheSpriteGlyphs.Count > 0) { //更新Cache的SpriteGlyph的Rect for (int i = 0; i < cacheSpriteGlyphs.Count; i++) { TMP_SpriteGlyph glyph = cacheSpriteGlyphs[i]; string spriteName = cacheSpriteCharacters[(int)glyph.index].name; if (glyphRectDic.ContainsKey(spriteName)) { GlyphRect newRect = glyphRectDic[spriteName]; glyph.glyphRect = new GlyphRect(newRect.x, newRect.y, newRect.width, newRect.height); } } } foreach (KeyValuePair <string, GlyphRect> glyphRect in glyphRectDic) { TMP_SpriteCharacter findSpriteCharacter = cacheSpriteCharacters.Find(character => character.name == glyphRect.Key); TMP_SpriteCharacter newSpriteCharacter = newSpriteCharacters.Find(character => character.name == glyphRect.Key); if (findSpriteCharacter == null) { //新增的Sprite TMP_SpriteGlyph spriteGlyph = new TMP_SpriteGlyph(); spriteGlyph.sprite = null; spriteGlyph.atlasIndex = 0; spriteGlyph.scale = 1.0f; spriteGlyph.index = (uint)cacheSpriteGlyphs.Count; GlyphMetrics metrics = newSpriteCharacter.glyph.metrics; spriteGlyph.metrics = new GlyphMetrics(metrics.width, metrics.height, metrics.horizontalBearingX, metrics.horizontalBearingY, metrics.horizontalAdvance); spriteGlyph.glyphRect = new GlyphRect(glyphRect.Value.x, glyphRect.Value.y, glyphRect.Value.width, glyphRect.Value.height); cacheSpriteGlyphs.Add(spriteGlyph); TMP_SpriteCharacter spriteCharacter = new TMP_SpriteCharacter(0, spriteGlyph); spriteCharacter.glyphIndex = (uint)cacheSpriteCharacters.Count; spriteCharacter.scale = 1; spriteCharacter.name = glyphRect.Key; cacheSpriteCharacters.Add(spriteCharacter); } } //3.cache写入SpriteAsset TMP_SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath <TMP_SpriteAsset>(SpriteAssetPath); FieldInfo spriteCharacterTablePi = spriteAsset.GetType().GetField("m_SpriteCharacterTable", BindingFlags.NonPublic | BindingFlags.Instance); if (null != spriteCharacterTablePi) { spriteCharacterTablePi.SetValue(spriteAsset, cacheSpriteCharacters); } FieldInfo spriteGlyphTablePi = spriteAsset.GetType().GetField("m_SpriteGlyphTable", BindingFlags.NonPublic | BindingFlags.Instance); if (null != spriteGlyphTablePi) { spriteGlyphTablePi.SetValue(spriteAsset, cacheSpriteGlyphs); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
public void TextPopup(string text, TMP_SpriteAsset asset, Transform target, Color color, float scale) { StartCoroutine(thr_textPopup(text, asset, target, color, scale)); }
public static void CreateTextMeshProObjectPerform() { Object target = Selection.activeObject; // Make sure the selection is a texture. if (target == null || target.GetType() != typeof(Texture2D)) { Debug.LogWarning("A texture which contains sprites must first be selected in order to create a TextMesh Pro Sprite Asset."); return; } Texture2D sourceTex = target as Texture2D; // Get the path to the selected texture. string filePathWithName = AssetDatabase.GetAssetPath(sourceTex); string fileNameWithExtension = Path.GetFileName(filePathWithName); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePathWithName); string filePath = filePathWithName.Replace(fileNameWithExtension, ""); // Check if Sprite Asset already exists TMP_SpriteAsset spriteAsset = AssetDatabase.LoadAssetAtPath(filePath + fileNameWithoutExtension + ".asset", typeof(TMP_SpriteAsset)) as TMP_SpriteAsset; bool isNewAsset = spriteAsset == null ? true : false; if (isNewAsset) { // Create new Sprite Asset using this texture spriteAsset = ScriptableObject.CreateInstance <TMP_SpriteAsset>(); AssetDatabase.CreateAsset(spriteAsset, filePath + fileNameWithoutExtension + ".asset"); // Compute the hash code for the sprite asset. spriteAsset.hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteAsset.name); // Assign new Sprite Sheet texture to the Sprite Asset. spriteAsset.spriteSheet = sourceTex; spriteAsset.spriteInfoList = GetSpriteInfo(sourceTex); // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); } else { spriteAsset.spriteInfoList = UpdateSpriteInfo(spriteAsset); // Make sure the sprite asset already contains a default material if (spriteAsset.material == null) { // Add new default material for sprite asset. AddDefaultMaterial(spriteAsset); } } // Get the Sprites contained in the Sprite Sheet EditorUtility.SetDirty(spriteAsset); //spriteAsset.sprites = sprites; // Set source texture back to Not Readable. //texImporter.isReadable = false; AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(spriteAsset)); // Re-import font asset to get the new updated version. //AssetDatabase.Refresh(); }
private TMP_SpriteAsset GetSpriteAsset() { TMP_SpriteAsset asset = AssetDatabase.LoadAssetAtPath(_emojiSpriteAssetPath, (typeof(TMP_SpriteAsset))) as TMP_SpriteAsset; return(asset); }