Hello! Is it possible to move the TextMeshPro Essentials at the root of Assets/ to a subdirectory? If not, is it possible to implement this soon so that TextMeshPro is not cluttering up the Assets directory?
Thanks!
Hello! Is it possible to move the TextMeshPro Essentials at the root of Assets/ to a subdirectory? If not, is it possible to implement this soon so that TextMeshPro is not cluttering up the Assets directory?
Thanks!
The TMP Essential Resources are imported in āAssets/TextMesh Pro/ā¦ā. Since these resources like font assets, sprite assets, etc. can be edited and can be referenced in code or in the text itself, these resources must be contained in the Assets folder itself (ie. they cannot be contained outside the project or in the package as all packages are read-only).
Having them in Assets is fine, just not the root of the directory. Iād rather move them to a subdirectory in Assets, such as āAssets/Plugins/TextMesh Pro/ā¦ā for example
I do not recommend moving the āTextMesh Proā folder as although it is possible to move this folder to some other sub folder, as the TMP Essential Resources or TMP Examples & Extras get updated from time to time, this will make the re-import process more complicated in the future.
In terms of sub folders, please note that āPluginsā is a special folder in Unity reserved for Native plugins. As such, I would suggest using some other sub folder.
I understand. Would it be possible to support this natively in the future as part of TextMeshPro to avoid any issues if the assets are moved?
Although this is a minor issue, I would second this feature request. Perhaps an option to specify the TextMesh Pro folder path in the TextMesh Pro window within Project Settings would be a good middle ground?
I also second this request. I understand there may be strong reasons behind this.
But if we may end with 5 different tools similar to TextMeshPro, we wonāt be able to keep a cleaner structure under Assets folder in the project.
I would agree, having the ability to move the TMP to a subdirectory of āAssetsā would be nice to tidy up folder structures, especially when you are dealing with lots of plugins and packages.
any news about this? other unity packages also create folders that completely ruin our project structure. so it would be nice if we could define a default folder for unity to store such data.
I donāt know if this is normal but when I tried to move it unity just crashed.
Iāve cheked TMP_Settings ScriptableObject and figured out that Fonts and other stuff are located in relative path to a Resources folder in the project. So Iāve just copied all TMP Examples & Extras crap into my Resources folder in root of Assets.
Resources is also relative and can be anywhere, itās like a symlink. You could probably bury it in yet another dir.
Apologies for necro, but this is still the most relevant. Any update on this? This makes life hellish for those that need to stuff everything in 1 dir like for the asset store.
Currently going through this issue. TextMeshPro is a dependency for my asset. But all dependencies must be shoved into /Assets/MyAssetPackage/TextMeshPro/
Official word on a recommendation? This page is a ātop resultā when googling āwhere folder location textmeshpro asset packageā
Thanks!
Just got bitten by this as well. As several others have noted, itās not a huge issue, but I expect most developers would consider magical, fixed directory locations to be an unfortunate anti-pattern. Iāve not run across anything else in Unity that has such a strict baked-in location. And as others have suggested, this pattern would get ugly very quickly if other packages used the same approach.
Iād say this is not only annoying, but stupid. Imagine if every package did it like this, weād have tens of folders right in āAssetsā.
Now that TextMeshPro is core package, it should be held to the same standard.
Canāt you just do it in the same way as URP?
Have some global settings asset and let developer store it anywhere he wants.
Reference this asset by ProjectSettings, include it in the build and be done with it.
I donāt even understand why we have this conversation, itās no brainer.
Fing Resources folder, like itās still Unity 4 in 2014
Apologies for the tone of my post.
Iāve did some digging and you can do few things to solve this issue:
Use any resource folder:
e.g. Assets\Common\Resources\TMP_Settings.asset
TextMeshPro just tries to load TMP_Settings, it does not provide path, so any resource folder should work as long as the asset name matches
Use custom Resource Provider
This has advantage of not using Resources folder.
Youāll need two scripts, one for editor and one for runtime.
The editor script should be in Packages/com.some.package/Editor, the reason for this is that you want to load it together with packages (so itās available when TMP package loads).
Example:
using UnityEngine;
using UnityEditor;
using System;
using Object = UnityEngine.Object;
namespace TextMeshProFix.Editor
{
public class TextMeshProFixResourceProvider : ResourcesAPI
{
[InitializeOnLoadMethod]
static void Init()
{
if (overrideAPI == null)
{
overrideAPI = new TextMeshProFixResourceProvider();
}
}
protected override Object Load(string path, Type type)
{
if (type.Name == "TMP_Settings")
{
return AssetDatabase.LoadAssetAtPath("Assets\\MyFolder\\TMP_Settings.asset", type);
}
return base.Load(path, type);
}
}
}
The runtime script will be similar, except it will load settings in different way. Either it will grab it from AssetBundle, Adressables or from AlwaysIncluded assets (Resources.FindObjectsOfTypeAll).
ā¦aaand one more workaround, because of how Samples in Package Manager are handled in the com.unity.render-pipelines.core package.
When package manager is opened, Assets\TextMesh Pro does not exist and ANY asset is imported, TextMeshPro resources get reimported!
Iām amazes how something like this could be ever shipped, but whateverā¦
Following code runs before OnPostprocessAllAssets in com.unity.render-pipelines.core, creates the directory so the package āthinksā everything is okay and deletes it afterwards. Itās effective only when needed. (PackageManager window was opened since last domain reload - see NeedsWorkaround below).
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.Rendering;
/// <summary>
/// Package com.unity.render-pipelines.core has some code for importing package dependencing when importing samples.
/// It's poorly written and it always tried to import TextMeshPro resources when it detects that "Assets\TextMesh Pro" does not exist.
/// This workaround goes around that and creates the folder before the code is run in the package and deletes it after.
/// </summary>
[InitializeOnLoad]
public class TextMeshProResourcesWorkaround : AssetPostprocessor
{
static string m_createdDir = null;
static Func<Action<string>> m_getter = null;
class Before : AssetPostprocessor
{
[RunBeforePackage("com.unity.render-pipelines.core")]
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (NeedsWorkaround())
{
string path = Path.GetFullPath("Assets/TextMesh Pro");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
m_createdDir = path;
}
}
}
}
class After : AssetPostprocessor
{
[RunAfterPackage("com.unity.render-pipelines.core")]
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (m_createdDir != null)
{
Directory.Delete(m_createdDir);
m_createdDir = null;
}
}
}
private static bool NeedsWorkaround()
{
if (m_getter == null)
{
var field = typeof(CoreEditorUtils).Assembly.GetType("SampleDependencyImporter+SamplePostprocessor").GetStaticField("AssetImported");
m_getter = field.ToGetter<Action<string>>();
// Use reflection if you don't have extension methods like this ^^
// m_getter = () => (Action<string>)field.GetValue(null);
}
return m_getter() != null;
}
}