Search Unity

Bug Creating TMP_SpriteAsset via code buggy behaviour

Discussion in 'UGUI & TextMesh Pro' started by Chunikus, Mar 9, 2023.

  1. Chunikus

    Chunikus

    Joined:
    Sep 5, 2020
    Posts:
    28
    I tried to automate creating TMP sprite assets, and it seems to work i see the assets in the editor, they have correct name and sprite texture, they look just fine, but they don't load correctly on rich text tag call. (they seem to load prefab's texture, prefab is the tmp asset i clone to make a new one, since creating blank scriptable object of TMP sprite assets type has a lot more issues..

    So i have scriptable object room, room has an icon sprite. But i also want to automatically create and have tmp asset for that sprite and my room SO ends up calling this method, which is explanatory.


    Code (CSharp):
    1. public string CreateAnAssetForThisSprite(Sprite spriteInAssets, string prefixForAssetName)
    2.     {
    3.         // prefab asset is just working copy of TMP sprite asset i just copy it cause creating new instance through ScriptableObject.CreateInstance<>() seem to have even more problems
    4.        
    5.         var tex = spriteInAssets.texture;
    6.         prefabAsset.spriteSheet = tex; // assigning to prefab before i copy it
    7.  
    8.         // this is not imprtant i just create the same file name for new asset as was name of the sprite
    9.         var spritePath = AssetDatabase.GetAssetPath(spriteInAssets);
    10.         var arr = spritePath.Split("/");
    11.         var fileName = arr[arr.Length - 1];
    12.         arr = fileName.Split(".");
    13.         fileName = arr[0];
    14.         fileName = prefixForAssetName + fileName;
    15.         var finalPath = "Assets/Resources" + "/" + folderPathWhereToCreaterAssets + "/" + fileName + ".asset";
    16.         // .. end of file path code..
    17.  
    18.         var prefabPath = AssetDatabase.GetAssetPath(prefabAsset);
    19.         AssetDatabase.CopyAsset(prefabPath, finalPath); // also tried Object.Instantiate(prefabAsset); or AssetDatabase.CreateAsset() seems like it's the same result
    20.  
    21.         var newAsset = AssetDatabase.LoadAssetAtPath<TMP_SpriteAsset>(finalPath);
    22.         newAsset.spriteSheet = tex; //assigning again to new asset trying all the things.
    23.         EditorUtility.SetDirty(newAsset);
    24.  
    25.         return fileName; // is used to create sting for rich text
    26.     }
     
  2. Chunikus

    Chunikus

    Joined:
    Sep 5, 2020
    Posts:
    28
    So i did find how TMP creates asset via context menu, and it's complicated. Unfortunately i cannot extract body of the method to do the same, since some property/fields setters are internal.

    i can hijack it by doing something like this :

    Selection.activeObject = tex;
    TMP_SpriteAssetMenu.CreateSpriteAsset();
    Selection.activeObject = null;

    And it does work it will create the asset, but in the wrong folder, i have to replace it, and it also switched project window context to new asset, which defeats the purpose since i wanted it to happen behind the scenes when i assign new icon to my SO.

    But basically it's not a bug, creating TMP sprite assets via code is just not implemented/exposed.
     
  3. Chunikus

    Chunikus

    Joined:
    Sep 5, 2020
    Posts:
    28
    Nevermind i can set private fields using reflection, and it works now. I still have to adjust the sprites so they are properly aligned with text though so not that automatic as one would hope :)